Methods visibility in interface - java

Do all methods in an Interface has by default Public visibility mode?

All methods in an interface default to public.
See Java Language Specification 6.6.1 which states
All members of interfaces are
implicitly public.

All interface methods ARE public abstract, all interface fields are public static final...
see here.

Just to add to other answers here: all methods are public, however, if the interface itself is package-local then effectively all methods are also package-local.
You can therefore mix public and package-local methods, by making a package-local interface extend a public one.
public interface P{
void iAmPublic();
}
interface L extends P{
void iAmPackageLocal();
}
Here L effectively has one public and one package-local method. Clients from outside the package will only see iAmPublic(), whereas ones from inside the package will see both methods.
In the same way you can nest interfaces inside other classes to achieve even tighter method visibility.

Yes, all methods of an interface are public, and can't have any other access modifier (i.e. the default public access modifier is the only valid access modifier)

Yes, all methods in an interface are implicitly public and abstract.
Check Java language specification chapter 9.4

Related

Java 9 Interface : Why default Modifier Converted into public Modifier

My Question is about interface. I create an interface and define four methods: first method is a private method; second is a default method; third is a static method; and fourth is an abstract method.
After compiling this interface and checking its profile: the default method is converted into a public method, and both the static and abstract methods have a prepended public modifier. Why is this?
Code:
interface InterfaceProfile {
private void privateM() { //this method is hidden
System.out.println("private Method");
}
default void defaultM() {
System.out.println("Default Method");
}
static void staticM() {
System.out.println("Static Method");
}
void doStuff(); //by default adds the public modifier
}
InterfaceProfile class
D:\Linux\IDE\Workspace\OCA-Wrokspace\Ocaexam\src>javap mods\com\doubt\session\InterfaceProfile.class
Compiled from "InterfaceProfile.java"
interface com.doubt.session.InterfaceProfile {
public void defaultM();
public static void staticM();
public abstract void doStuff();
}
The fact that it's a default method doesn't make a difference. The implicit scope is public.
Here's what the tutorial says:
All abstract, default, and static methods in an interface are implicitly public, so you can omit the public modifier.
Simple: by default, all methods in an interface are public. You can restrict that by applying private, but whenever you do not do that, that default kicks in. Thus: there is no conversion taking place at all.
Quoting the Java Language Specification:
A method in the body of an interface may be declared public or private (§6.6). If no access modifier is given, the method is implicitly public. It is permitted, but discouraged as a matter of style, to redundantly specify the public modifier for a method declaration in an interface.
( the ability to have private methods in interfaces was introduced with Java 9, as people discovered that Java 8 default methods often created the need to have, well, private methods that such default methods could make use of, without making these helper methods publicly visible )
The default modifier is public, because that is how the interface declaration is defined:
https://docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
If you are asking for the reasoning behind this, i would argue that the purpose of defining an interface is to ensure the - well - interface of all implementing classes, meaning that all implementing classes have clear contracts on which public accessable methods they need to provide.
Adding private methods to an interface does not serve this primary purpose and seems to be more of an implementation hint. Private and abstract methods were late additions to interfaces.
Related: Should methods in a Java interface be declared with or without a public access modifier?
https://docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
All abstract, default, and static methods in an interface are implicitly public, so you can omit the public modifier.
In effect, a class that implements an interface exposes all of the interface methods (other than private) to any other code that has visibility of the class.
It would be very confusing if a class had an interface but the methods on the interface would be visible to some code and not other. If you want to selectively expose methods, then you should probably make use of multiple interfaces.
public interface Profile {
generalMethod() ...
}
public interface SecretProfile extends Profile {
secretMethod() ...
}
Classes may choose to implement either of the interfaces (or even both). 3rd party code can check for the presence of the interface and know that the method is available or not.

Why `private static` field is not allowed in Java 8 interface?

When I'm trying to compile the following code
public interface SomeInterface{
private static Logger logger = Logger.getLogger();
public default void someMethod(){
logger.info("someMethod: default implementation");
}
}
I get an error
Illegal modifier for the interface field SomeInterface.logger; only public, static & final are permitted
When I delete private modifier, code compiles, but I don't want other classes from the package to see this field.
Why Java doesn't allow me to do such thing when it actually does make sense?
In the pre-Java-8 view of the world, interfaces were purely for interface contracts, and private members exist purely for implementation, so this restriction was completely sensible.
In the post-Java-8 world, where interfaces can carry behavior (but not state), it starts to be reasonable to ask whether other features of classes should be applied to interfaces as well. (However, just because something might be "reasonable" doesn't mean it must be supported; there is often more than one reasonable way to construct the world.)
In Java 9, private methods in interfaces will be supported.
Interfaces are not classes. They have no private state. Even a public logger in the interface is a design smell and an abuse of interfaces.
The use case for static fields in interfaces is mainly for compile-time constants, not for stateful objects.
The goal of interface is to define something implemented by other classes. A private field does not define anything as it is not visible outside the interface. Hence it does not make any sense in this construct. It may be some hacks how to use it (maybe from interface inner classes) but would not look like a good design anyway.
If you actually implement part of the functionality, use abstract class instead.
Interface is like a blueprint of any class, where you declare your members. Any class that implement that interface is responsible for its definition.
Private members can only be accessed by same class member, which does not make sense in terms of interface.
Protected members can be accessed by same class member and inherited class members, but in case of interface we never extend an interface, we implement it. So any interface can only contain public methods generally,
public interface SomeInterface {
public default void someMethod() {
SomeInterfaceInternal.logger.info("someMethod: default implementation");
}
}
final class SomeInterfaceInternal {
protected static final Logger logger = LoggerFactory.getLogger(SomeInterface.class);
}

Why a method must be public?

Consider the following classes:
class A {
void print() {
System.out.println("A");
}
}
class B extends A implements C {
}
public interface C {
void print();
}
I get this error:
The inherited method A.print() cannot hide the public abstract method
in C
Now, I understand that print() must be public in order the eliminate the compilation error, but what's the reason behind this?
The answer is simple interface methods are always public or else just use composition instead of inheritance. Also to note that while overriding a method you can not narrow down the access level of the method.
The Oracle Docs says:
The access modifier public (§6.6) pertains to every kind of interface
declaration.
B#print can never be truly private, because anyone can call it via the interface:
B b = new B();
C c = b;
c.print();
Java doesn't let you pretend it's private when it is effectively public. (C++ does; different languages make different trade-offs.)
The method void print() in class A is implementation for the interface method declaration. Now , in the interface C this method is public ( every interface method is public by default ) and the rules of OOP ( Liskov principle in particular ) dictates that the visibility of this method's implementation in class A cannot be lower than that in its interface - hence it has to be public.
Short answer is because Java doesn't allow it. According to the Java Language Specification under 9.1.1. Interface Modifiers - JLS-9.1.1,
The access modifier public (§6.6) pertains to every kind of interface declaration.
The access modifiers protected and private pertain only to member interfaces within a directly enclosing class or enum declaration (§8.5.1).
So if you don't specify an access modifier in your non-member interface (like void print()) it is public and your class which implements that interface must provide a public void print().
Well, think it this way: if an interface defined private methods then these methods would only be called by the class implementing the interface, and that doesn't make much sense, since (in Java) an interface defines the contracts between classes. When a class follows an interface then the methods defined in the interface can be called in the implementation by external classes.
In your case, your class B is extending A while class A is not implementing the interface C. So, by extending A it inherits a method that has less access than the one defined in the interface, and that is not allowed.
If your class A had implemented the interface you would have seen the error "Cannot reduce the visibility of the inherited method from C"
All the methods in an interface are implicitly public. The names and return types of the methods(the ones B inherits from A and C) are same in your case but the visibility modifiers are different. And if you change the visibility modifier of an inherited method the compiler will complain because you cannot reduce the visibility of an inherited member.

Differences on Interface implementation [duplicate]

This question already has answers here:
Should methods in a Java interface be declared with or without a public access modifier?
(12 answers)
Closed 8 years ago.
I have maybe a simple question.
Here two code-snippets to show what I mean:
Example 1:
public interface SomeInterface{
public void someMethod(...);
}
Example 2:
public interface AnotherInterface{
void anotherMethod(...);
}
So, Example 1 is completely clear to me but Example 2 isnt.
In fact, is there any difference between those two examples expect the public-modifier?
On one hand I found that methods from Interfaces are implicitly public but on the other hand I have found that methods declared in an Interface are "package-public" (I dont now if thats the correct description) - saying these are visible to all classes in the same package as the Interface.
For now I am completely confused.. So could someone please explain me whats right?
Thanks anyways.
It's redundant to declare it public. In particular JLS 9.4 states:
Every method declaration in the body of an interface is implicitly public (§6.6).
Every method declaration in the body of an interface is implicitly abstract, so its body is always represented by a semicolon, not a block.
It is permitted, but discouraged as a matter of style, to redundantly specify the public and/or abstract modifier for a method declared in an interface.
All interface methods are public abstract and all interface fields are public static final.
So there is no difference in above examples.
All methods in an interface are public and visible to implementing classes everywhere. But if the interface itself is package local (has no modifier - the default), then those methods are visible only to classes/interfaces within the same package. But the method would still have to be public in the implementing class
In the code you have above, there is no difference. But if it had been:
interface AnotherInterface{ // Note no modifier - default modifier applied
void anotherMethod(...);
}
In this case, the interface is visible only inside the same package.
NOTE: It's the interface itself that can be package-private, not the methods in it. You can define an interface that can only be used (by name) within the package it's defined in, but its methods are public like all interface methods. If a class implements that interface, the methods it defines must be public. The key thing here is that it's the interface type that isn't visible outside the package, not the methods.

Java Interfaces -- why not have private methods?

Why are methods on interfaces always public? Why can't they be private?
Because all methods on an interface are public. That's the point in having the interface -- technically it defines a contract for your class (which may have many, overlapping, contracts/interfaces). The client of your class should hold a reference to the interface and have access only to the class' published (public) methods through the interface.
I infer that you are referring to an interface declared thusly:
public interface MyInter
{
public void myFunc();
}
And the resulting error if you omit the public qualifier in your implementation:
MyClass.java:3: myFunc() in MyClass cannot implement myFunc() in MyInter; attempting to assign weaker access privileges; was public
void myFunc(){}
^
Say you could make myFunc private. You write the following code in a different class. This should complain about you trying to use a private function you didn't have access to:
MyClass foo = new MyClass();
foo.myFunc(); // Declared private, can't call it.
But what about this:
void doSomething(MyInter foo)
{
foo.myFunc(); // Declared public in interface, private in implementation.
}
Can we do this? According to the interface it's a public method so we should be good to go. But it's implemented as a private method so the class expects it never to be called from the outside like this, a restriction that should be enforced by the compiler. But the compiler doesn't even need to know about MyClass for this to compile. It could not even be written yet, or in an external library that may or may not ever be integrated.
Allowing implementations creates an internal inconsistency in the rules of allowable access, and the resolution to that inconsistency is to disallow the situation altogether. Anything that can call a method in an interface must be able to call it in any implementation.
The same argument holds true for overriding subclass methods. You can't "hide" them by overriding with more restrictive qualifiers.
Why is it so?
Because the JLS says so:
In the Chapter on interface declarations, JLS 9.4 says: "Every method declaration in the body of an interface is implicitly public."
In the Chapter on class declarations, JLS 8.4.8.3 says: "The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, ..."
Engineer Dollery's answer explains why the language is designed this way.

Categories