Want interface with some public and some package level access

Discussion in 'Java' started by Jim Cobban, Apr 10, 2004.

  1. Jim Cobban

    Jim Cobban Guest

    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
    34 Palomino Dr.
    Kanata, ON, CANADA
    K2M 1M1
    +1-613-592-9438
     
    Jim Cobban, Apr 10, 2004
    #1
    1. Advertising

  2. Jim Cobban

    fox_fire Guest

    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.
     
    fox_fire, Apr 11, 2004
    #2
    1. Advertising

  3. Jim Cobban

    fox_fire Guest

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

    a) "the public methods and fields ....
     
    fox_fire, Apr 11, 2004
    #3
  4. Jim Cobban

    Chris Uppal Guest

    Jim Cobban wrote:

    > 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
     
    Chris Uppal, Apr 11, 2004
    #4
  5. Jim Cobban

    Carla Lamp Guest

    "Jim Cobban" <> wrote in message news:<>...
    > 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.
     
    Carla Lamp, Apr 11, 2004
    #5
  6. Jim Cobban

    Jim Cobban Guest

    "Carla Lamp" <> wrote in message
    news:...
    >
    > 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.
     
    Jim Cobban, Apr 13, 2004
    #6
  7. Jim Cobban

    Carla Lamp Guest

    "Jim Cobban" <> wrote in message news:<>...
    > "Carla Lamp" <> wrote in message
    > news:...
    > >
    > > 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.


    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
    ) ) ; }
    }
     
    Carla Lamp, Apr 13, 2004
    #7
  8. Jim Cobban

    Tony Morris Guest

    > 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
     
    Tony Morris, Apr 13, 2004
    #8
  9. Jim Cobban

    Tony Morris Guest

    "Carla Lamp" <> wrote in message
    news:...
    > "Jim Cobban" <> wrote in message

    news:<>...
    > > "Carla Lamp" <> wrote in message
    > > news:...
    > > >
    > > > 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.

    >
    > 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
     
    Tony Morris, Apr 13, 2004
    #9
  10. Jim Cobban

    Roedy Green Guest

    On 13 Apr 2004 15:14:54 -0700, (Carla Lamp)
    wrote or quoted :

    >> 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.


    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.



    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
     
    Roedy Green, Apr 18, 2004
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page