默认方法和编译时错误:继承的方法Horse.identifyMyself()无法隐藏Flyer

时间:2015-11-24 18:59:02

标签: java inheritance methods default

以下查询基于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方法时,特别是当abstractdefault是相互排斥的关键词时!

提前感谢您的耐心和投入。

此致 Nawazish

2 个答案:

答案 0 :(得分:0)

Pegasus扩展了Horse,因为它没有自己的identifyMyself()方法,所以它继承了Horse中定义的那个,现在是私有的,因为你从中删除了公共。现在,因为Pegasus还实现了Mythical,它定义了将自己标识为公共的方法,Pegasus必须拥有此方法的公共版本,但它只有一个私有版本,所以你得到这个错误。与C ++不同,您无法将重写方法的可见性从公共更改(私有)(或受保护)。

答案 1 :(得分:0)

  1. 继承的方法Horse.identifyMyself()无法隐藏神话中的公共抽象方法

    接口中声明的所有方法都是隐式公开的。

    接口中的所有抽象,默认和静态方法都是隐式的 public,所以你可以省略public修饰符。

    你的班飞马正在扩展马并实施传单,神话 有相同的方法identifyMyself()所以来自类Horse的方法将是首选 但是你将Horse.identifyMyself()的可见性降低到默认值 你将公众从中移除,因为你正在进行编译 如果您使用Horse.identifyMyself()方法,则会将其删除 公众也是。

  2. 因为我们正在降低Horse.identifyMyself()从公共到包私有的可见性,所以它无法隐藏从接口继承的公共方法

    当您将其设为私有时,您的班级Pegasus将无法访问 它。

  3. 另一个问题是,为什么编译器将Mythical.identifyMyself()称为“抽象方法”时,为什么它被声明为默认方法,特别是当abstract和default是互斥的关键词时!

    当编译器将Mythical.identifyMyself()称为“抽象方法”时, 它只是压倒一切。

相关问题