以下查询基于this官方Oracle文档。在本文档的标题"接口方法"下的子节"实例方法优于接口默认方法。",有几个类定义如下:
public class Horse {
public String identifyMyself() {
return "I am a horse.";
}
}
public interface Flyer {
default public String identifyMyself() {
return "I am able to fly.";
}
}
public interface Mythical {
default public String identifyMyself() {
return "I am a mythical creature.";
}
}
public class Pegasus extends Horse implements Flyer, Mythical {
public static void main(String... args) {
Pegasus myApp = new Pegasus();
System.out.println(myApp.identifyMyself());
}
}
一切都很好,规则认为超级类的继承实例方法优于超级接口的继承默认方法;但是,每当我从方法public
中删除Horse.identifyMyself()
访问修饰符时,我都会收到以下编译时错误:
The inherited method Horse.identifyMyself() cannot hide the public abstract method in Mythical
老实说,我无法完全推断出这个编译错误。我能够想到的可能解释是,由于我们正在降低Horse.identifyMyself()
从public
到package-private的可见性,因此隐藏了从接口继承的public
方法失败。如果这是正确的,那么为什么编译器会给出新的错误消息,它可能只是保留了旧的,众所周知的消息:" Cannot reduce the visibility of the inherited method...
"
另一个问题是为什么编译器将Mythical.identifyMyself()
称为"抽象方法"当它被声明为default
方法时,特别是当abstract
和default
是相互排斥的关键词时!
提前感谢您的耐心和投入。
此致 Nawazish
答案 0 :(得分:0)
Pegasus扩展了Horse,因为它没有自己的identifyMyself()方法,所以它继承了Horse中定义的那个,现在是私有的,因为你从中删除了公共。现在,因为Pegasus还实现了Mythical,它定义了将自己标识为公共的方法,Pegasus必须拥有此方法的公共版本,但它只有一个私有版本,所以你得到这个错误。与C ++不同,您无法将重写方法的可见性从公共更改(私有)(或受保护)。
答案 1 :(得分:0)
继承的方法Horse.identifyMyself()
无法隐藏神话中的公共抽象方法
接口中声明的所有方法都是隐式公开的。
接口中的所有抽象,默认和静态方法都是隐式的 public,所以你可以省略public修饰符。
你的班飞马正在扩展马并实施传单,神话
有相同的方法identifyMyself()
所以来自类Horse的方法将是首选
但是你将Horse.identifyMyself()的可见性降低到默认值
你将公众从中移除,因为你正在进行编译
如果您使用Horse.identifyMyself()
方法,则会将其删除
公众也是。
因为我们正在降低Horse.identifyMyself()
从公共到包私有的可见性,所以它无法隐藏从接口继承的公共方法
当您将其设为私有时,您的班级Pegasus将无法访问 它。
另一个问题是,为什么编译器将Mythical.identifyMyself()称为“抽象方法”时,为什么它被声明为默认方法,特别是当abstract和default是互斥的关键词时!
当编译器将Mythical.identifyMyself()
称为“抽象方法”时,
它只是压倒一切。