Want interface with some public and some package level access

J

Jim Cobban

I am a bit puzzled by the way that interfaces are defined. As I read it all
members of an interface are public by definition and it is even discouraged
to bother specifying public since it is the only possible value. So either
an entire interface is public, and therefore part of the contract between
the package and the outside world, or else the entire interface is package
level access.

If I have understood this correctly, this is a pain in the butt. I have a
class that provides services some of which are used only within the package
and others that may be provided to other packages. Both internal and
external users access these services through an interface, not by
referencing the class itself, because they do not care about the internal
implementation of the class and therefore do not need to be recompiled if I
change the internal implementation. Using an interface also eliminates
circular references.

However Java will not permit me to define some of the methods in an
interface to be public access and others package access. This in turn
prevents me from defining the actual implementations as package access.
Peculiarly although to my mind I am trying to define stronger security on
those methods Java complains about "weaker" access. That language is
strange: Would you say a locked room labelled "authorized personel only" has
"weaker" access than one that is publicly accessable?

I suppose I could define two distinct interfaces, one public and one
package, that would both be implemented by my class, but then any other
member of my package that needed to access both the public and package level
interface of the class would need to cast back and forth.

How do others define their package interfaces so as to make what they want
public while hiding what the outside world does not need to see?

--
Jim Cobban (e-mail address removed)
34 Palomino Dr.
Kanata, ON, CANADA
K2M 1M1
+1-613-592-9438
 
F

fox_fire

I have two possible solutions to your problem

1) There are 2 meanings to the word "interface."
I think you might be confusing the two.
Interface means:
a) "the public (or package, sometimes) methods and fields through which a
class can be accessed"

and it also means

b) "a Java source file that is designated an interface and contains only
public method headers and static final class variables"

When you say your class is accessed "through an interface" that denotes
the public methods of the class and has nothing to do with implements
xxxinterface etc.


2) If you actually mean interfaces, as a Java component,
then the reason everything is public is because there is no implementation
to an interface and therefore no reason to make anything less than
public.

You can implement an interface in a class that has package-access only,
but its methods still must be public.

public interface MyInterface
{
void dostuff();
}

class MyClass implements MyInterface
{
public void dostuff() { }
}

MyClass is still a package-level class.
 
F

fox_fire

I made an error in my previous post.
I meant to say

a) "the public methods and fields ....
 
C

Chris Uppal

Jim said:
How do others define their package interfaces so as to make what they want
public while hiding what the outside world does not need to see?

Basically, you can't. You can make an interface package-private, but any class
that implements it must do so using explicitly public methods. This, IMO, is
stupid, but that's how the language is defined.

The nearest you can get is to use package-private interfaces, that are
implemented by public methods of classes that are themselves private to that
package.

Either that or give up on the idea of using interfaces to define the contracts
between classes in the same package.

-- chris
 
C

Carla Lamp

Jim Cobban said:
I am a bit puzzled by the way that interfaces are defined. As I read it all
members of an interface are public by definition and it is even discouraged
to bother specifying public since it is the only possible value. So either
an entire interface is public, and therefore part of the contract between
the package and the outside world, or else the entire interface is package
level access.

If I have understood this correctly, this is a pain in the butt. I have a
class that provides services some of which are used only within the package
and others that may be provided to other packages. Both internal and
external users access these services through an interface, not by
referencing the class itself, because they do not care about the internal
implementation of the class and therefore do not need to be recompiled if I
change the internal implementation. Using an interface also eliminates
circular references.

However Java will not permit me to define some of the methods in an
interface to be public access and others package access. This in turn
prevents me from defining the actual implementations as package access.
Peculiarly although to my mind I am trying to define stronger security on
those methods Java complains about "weaker" access. That language is
strange: Would you say a locked room labelled "authorized personel only" has
"weaker" access than one that is publicly accessable?

I suppose I could define two distinct interfaces, one public and one
package, that would both be implemented by my class, but then any other
member of my package that needed to access both the public and package level
interface of the class would need to cast back and forth.

How do others define their package interfaces so as to make what they want
public while hiding what the outside world does not need to see?

What you can do is define two interfaces: PublicInterface and
PackageInterface (you probably want different names). PublicInterface
defines all the methods you wish to share with the public and
PackageInterface extends PublicInterface by adding the methods you only want
to share within your package.

Then you define your implementing class Impl as implementing
PackageInterface. Whenever you pass an Impl reference outside your
package, cast it as a PublicInterface. Whenever you pass an Impl
reference inside your package, cast it as a PackageInterface.
 
J

Jim Cobban

Carla Lamp said:
What you can do is define two interfaces: PublicInterface and
PackageInterface (you probably want different names). PublicInterface
defines all the methods you wish to share with the public and
PackageInterface extends PublicInterface by adding the methods you only want
to share within your package.

Then you define your implementing class Impl as implementing
PackageInterface. Whenever you pass an Impl reference outside your
package, cast it as a PublicInterface. Whenever you pass an Impl
reference inside your package, cast it as a PackageInterface.

Thank you for that suggestion.

I still see a problem. Because all methods in an interface must be public,
those methods in any class that implements the interface must be public.
But if ANY public method in such a class must be visible outside the package
then ALL public methods in that class must be visible outside the package.
So even if I put some of those methods into PackageInterface, they would in
fact still be visible to anyone who referenced the class itself, even if I
do not want those methods to be visible outside the class.

Unless someone can convince me otherwise that says to me that the definition
of an interface in Java is a gross violation of data protection because it
forces me to make information public that I do not want to be public. This
is extremely upsetting.
 
C

Carla Lamp

Jim Cobban said:
Thank you for that suggestion.

I still see a problem. Because all methods in an interface must be public,
those methods in any class that implements the interface must be public.
But if ANY public method in such a class must be visible outside the package
then ALL public methods in that class must be visible outside the package.
So even if I put some of those methods into PackageInterface, they would in
fact still be visible to anyone who referenced the class itself, even if I
do not want those methods to be visible outside the class.

Unless someone can convince me otherwise that says to me that the definition
of an interface in Java is a gross violation of data protection because it
forces me to make information public that I do not want to be public. This
is extremely upsetting.

A simple abstract example is below. Inside the package, classes can
refer directly to the element member of DooHickey as a
PackageInterface. This
means they can use the packageThing method. Outside the package, the
only access to the element member of DooHickey is through the
getElement
method. This method returns a PublicInterface so they can only use
the publicThing method.

Using the Wrapper is not necessary if you are OK with outside
classes discovering stuff by introspection.

public interface PublicInterface { public void publicThing () ; }

public interface PackageInterface extends PublicInterface { public
void packageThing () ; }

class Impl implements PackageInterface {
public void publicThing ( ) { } public void packageThing ( ) { } }

public class Wrapper implements PublicInterface {
private PublicInterface pub ;
public Wrapper ( PublicInterface pub ) { this . pub = pub ; }
public void publicThing ( ) { this . pub . publicThing ( ) ; } }

public class DooHickey {
PackageInterface element = new Impl ( ) ;
public PublicInterface getElement ( ) { return ( new Wrapper ( element
) ) ; }
}
 
T

Tony Morris

Unless someone can convince me otherwise that says to me that the
definition
of an interface in Java is a gross violation of data protection because it
forces me to make information public that I do not want to be public. This
is extremely upsetting.

I certainly don't intend to convince you that an interface having implicit
public only methods is the right thing to do, since I have no ambition at
this stage to write a book on software design.

What I can do is suggest that what you are trying to do probably has a much
better solution than trying to "hack around" the design intention of Java
interfaces. Until I know exactly what that is, I will have to consider your
point of view to be yet another naive and misinformed opinion.

--
Tony Morris
(BInfTech, Cert 3 I.T.)
Software Engineer
(2003 VTR1000F)
Sun Certified Programmer for the Java 2 Platform (1.4)
Sun Certified Developer for the Java 2 Platform
 
T

Tony Morris

Carla Lamp said:
"Jim Cobban" <[email protected]> wrote in message

A simple abstract example is below. Inside the package, classes can
refer directly to the element member of DooHickey as a
PackageInterface. This
means they can use the packageThing method. Outside the package, the
only access to the element member of DooHickey is through the
getElement
method. This method returns a PublicInterface so they can only use
the publicThing method.

Using the Wrapper is not necessary if you are OK with outside
classes discovering stuff by introspection.

public interface PublicInterface { public void publicThing () ; }

public interface PackageInterface extends PublicInterface { public
void packageThing () ; }

class Impl implements PackageInterface {
public void publicThing ( ) { } public void packageThing ( ) { } }

public class Wrapper implements PublicInterface {
private PublicInterface pub ;
public Wrapper ( PublicInterface pub ) { this . pub = pub ; }
public void publicThing ( ) { this . pub . publicThing ( ) ; } }

public class DooHickey {
PackageInterface element = new Impl ( ) ;
public PublicInterface getElement ( ) { return ( new Wrapper ( element
) ) ; }
}

Side Note: Applying redundant modifiers to interface methods and members is
a violation of convention (in this case, the public access modifier).
All interface methods are implicitly public; all interface members are
implicitly public, static and final - there is no need to specify any of
these modifiers.

--
Tony Morris
(BInfTech, Cert 3 I.T.)
Software Engineer
(2003 VTR1000F)
Sun Certified Programmer for the Java 2 Platform (1.4)
Sun Certified Developer for the Java 2 Platform
 
R

Roedy Green

You have two privacy weapons. The public/private scope of individual
methods and just what sort of handles you give people. If you hand
someone an interface handle there is no guarantee about what sort of
object is backing it up.

Unless they cast it to a class that has more methods that exposed in
the interface they can't get at those additional methods. That class
itself can be non-public. That way you selectively expose only the
methods you want with a set of interfaces on that class. It gives you
very fine control.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top