考虑以下课程:
class A {
void print() {
System.out.println("A");
}
}
class B extends A implements C {
}
public interface C {
void print();
}
我收到此错误:
继承的方法A.print()无法隐藏公共抽象方法 在C
现在,我了解print()
必须公开才能消除编译错误,但这背后的原因是什么?
答案 0 :(得分:6)
答案是简单的接口方法总是公共的,否则只使用组合而不是继承。另请注意,在覆盖方法时,您无法缩小方法的访问级别。
Oracle Docs说:
访问修饰符public(第6.6节)适用于各种接口 声明。
答案 1 :(得分:5)
B#print
永远不会真正私密,因为任何人都可以通过界面调用它:
B b = new B();
C c = b;
c.print();
当Java被公开时,它不会让你假装它是私有的。 (C ++可以;不同的语言做出不同的权衡。)
答案 2 :(得分:4)
void print()
中的方法class A
是接口方法声明的实现。现在,在interface C
中,此方法为public
(默认情况下每个接口方法都是公共的),OOP规则(特别是Liskov原则)规定了此方法在{{1}中的实现的可见性不能低于其界面中的那个 - 因此它必须是class A
。
答案 3 :(得分:2)
简短回答是因为Java不允许它。根据9.1.1下的Java语言规范。界面修饰符 - JLS-9.1.1,
访问修饰符public(第6.6节)适用于各种接口声明。
访问修饰符protected和private仅适用于直接封闭类或枚举声明(第8.5.1节)中的成员接口。
因此,如果您未在非成员界面中指定访问修饰符(如void print()
),则它是公共的,并且实现该界面的类必须提供public void print()
。
答案 4 :(得分:1)
好吧,这样想吧:如果接口定义了私有方法,那么这些方法只会被实现接口的类调用,并且不会使太多有意义,因为(在Java中) )接口定义类之间的契约。当一个类跟随接口时,接口中定义的方法可以在外部类的实现中调用。
在您的情况下,您的B类正在扩展A而A类未实现接口C.因此,通过扩展A,它继承的访问权限少于接口中定义的访问权限,这是不允许的。
如果您的A类已经实现了接口,您会看到错误“无法降低C中继承方法的可见性”
答案 5 :(得分:1)
接口中的所有方法都是隐式public
。方法的名称和返回类型(B继承自A和C)在您的情况下是相同的,但可见性修饰符是不同的。如果您更改继承方法的可见性修饰符,编译器会抱怨,因为您无法降低继承成员的可见性。