• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Default public access modifier for interfaces members?

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Members of an interface are defined by the language to have public access modifiers, by default. However, usually the lack of an access modifier implies package, so its confusing why Java defaults to public here (or atleast, its inconsistent).
If it really was package, then I belive that classes which implemented the interface could widen the accessibility of the implemented functions by making them public (exactly the same as you can do with inheritance using "extends"). However, because they are public, you cannot restrict the access in the derived classes. For instance, the derived class couldn't make it private.
For example, you cannot treat a class polymorphically within the package using the implemented interface functions, but not export those functions to other packages (since by default they are public). This seems to be violating information hiding - i want the public API to be a subset of the package API, but I cant do that with functions derived from an interface, because they all must be public.
Do anyone understand why Java was defined like this?
I guess you could argue that classes that implement an interface must publicly support that interface, and if you want to get around it, you could by making the interface into an abstract base class. But what if you already have an inheritance relationship, and adding the interface stuff to the base class just pollutes what the base class really represents.
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
David,
Methods declared in an interface are implicitly abstract and public. "By default" would imply that you could change that, but you can't. You can still limit access to the implemented interface methods by giving the implementing class package, protected, or even private visibility. That way even if the interface methods have public visibility, only classes that can actually access the implementing class can invoke the interface methods.
 
David Neiss
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for your reply.
What I had wanted though was to have the classes in a package that implemented a package specific interface to be publicaly available w/o the implemented functions being part of the public API (why? because the functions that are implemented are part of the implementation of the class, not part of the publicly accessible API).
I guess what bugs me is that the language authors made a conscious effort to restrict the language in this way (at the cost of inconsistency), but for what gain?
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
David, I'm not quite getting what you want to do, especially when you say "a package-specific" (friendly access?) interface that should be publicly available. Perhaps if you post some code, we could get a clearer picture of the situation.
Here's some code that illustrates what I said before:


[This message has been edited by JUNILU LACAR (edited July 27, 2001).]
 
David Neiss
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks again for your follow up. Here is what im saying:
//**** File 1 *******************************************
package Package1;
class BaseClass
{
void someBaseClassFunction() {}
int someBaseClassData;
}
interface Interface
{
void interfaceFunction();
}
public class Package1PublicClass extends BaseClass implements Interface
{
public static void main(String []args)
{
System.out.println("Package1PublicClass");
}
public void interfaceFunction()
{
System.out.println("Package1PublicClass.interfaceFunction()");
}
}

//**** File 2 ************************************************
package Package2;
import Package1.*;
public class Package2PublicClass
{
public static void main(String []args)
{
System.out.println("Package2PublicClass");
Package1PublicClass c = new Package1PublicClass();
c.interfaceFunction();
//^ I don't want to allow this, but have no way
// to prevent it based on public access modifer
// in the interface
// c.someBaseClassFunction();
//^This is a compilation error, which is what i want
}
}
//*********************************************************
What I want is to be able to treat classes that implement Package1.Interface polymorphically within Package1. That is, classes within Package1 can call the function interfaceFunction() on classes that implement Package1.Interface. However, I don't want classes outside Package1 to be able to call the function interfaceFunction().
If the Java language was written such that members of interfaces were given package access by default, then the function Package1PublicClass.interfaceFunction() could also have package access, and classes outside of the Package would not be able to call interfaceFunction() in classes that implemented that interface.
However, it appears that you have no choice in the matter because Java defines that all members of an interface be public. You cannot make its access more restrictive in the implementing class and therefore limit the accessibility of these functions to only package access.
So, you are stuck with not being allowed to restrict the accessibility of functions that are "inherited" from interfaces. However, there seems to be no such restiction for functions that are "inherited" via the extends clause. The line c.someBaseClassFunction(); wont compile because the base class defined someBaseClassFunction() to have package access, and the derived class also defines someBaseClassFunction() to also have package access, so I cannot call it from Package2, which is what I want.
So, I understand that there is this restiction in Java, but I dont understand why the language was defined this way.
It seems that by doing this (making members of interfaces public), they:
1) Broke the consistency of the language w.r.t. modifiers. In all other places, the absense of a modifier implies package access. For interfaces, it implies public.
2) Makes it impossible to achive the kind of access restriction that is possible with classes that I have shown above.

So, I see two negatives as a result of this decision in the language, but no positives. What am i missing?
 
No. No. No. No. Changed my mind. Wanna come down. To see this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic