简体   繁体   中英

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM