【问题标题】:Implementing and extending, Interface and Abstract class respectively with same method name in java在java中分别使用相同的方法名实现和扩展接口和抽象类
【发布时间】:2019-09-23 15:54:01
【问题描述】:

我正在尝试了解默认方法如何在各种情况下处理钻石问题。
而且,这是我无法理解的场景之一。

以下是描述,
1. 带有默认方法的接口method()
2. 带有方法的抽象类method()
3. 实现上述接口并扩展抽象类的具体类。

interface Interface {
    default void method() {
        System.out.println("Interface method");
    }
}


abstract class AbstractClass {
    void method() {
            System.out.println("Abstract class method");
    }
}


// Concrete class definition first starts
public class ConcreteClass extends AbstractClass implements Interface {

    @Override
    public void method() {
        super.method();
    }

    public static void main(String[] args) {
        Interface test = new ConcreteClass();
        test.method();
    }
}
// Concrete class definition first ends

// Concrete class definition Second starts
public class ConcreteClass extends AbstractClass implements Interface {

    public static void main(String[] args) {
        Interface test = new ConcreteClass();
        test.method();
    }
}
// Concrete class definition Second ends

我的查询,

1. 为什么定义首先总是以“抽象类方法”的形式输出,即使我使用接口类型作为具体的类对象?
2. 为什么定义第二个不编译?
如果编译器首先在定义中使用抽象类实现,那么它应该能够识别出它将始终在第二个定义中使用抽象类实现。

这种行为让我很困惑,非常感谢任何帮助。 否则,我越深入研究,它就越混乱。


编辑 1:
第二个定义的编译错误是“继承的方法AbstractClass.method()不能隐藏接口中的公共抽象方法”

【问题讨论】:

  • (1) “即使我将具体的类对象转换为接口”cast 是什么意思? (2) 你得到什么编译错误(它应该包含 why 部分的答案)?
  • 添加编译错误。

标签: java java-8


【解决方案1】:

默认方法就是:默认值。如果有实现,就会被使用。如果没有,将使用默认值。这里没有菱形问题(但是可以有多个默认值)。

1) Dynamic dispatch

2) 抽象类给了名为method的方法包私有访问;接口要求它是公开的。

【讨论】:

  • @dSanders 具体关于 (1),AbstractClass 为 method() 指定了一个实现,它覆盖了默认的 Interface::method。抽象类的任何子类都将调用 AbstractClass::method,除非该子类通过依次定义 Subclass::method 来覆盖它。
  • 好的,所以默认方法被用作方法定义的最后手段。 “抽象类为名为方法包的方法提供了私有访问权限;接口要求它是公共的。”我没有得到这个。
  • 如果你有一个接口,无论你是否添加public关键字,方法都是隐式公开的。抽象类中的方法不是公开的。它是在默认访问级别(包私有)定义的。问题是私有包比公共包更严格。
  • 哦,我明白了。所以编译错误来了,因为 Abstract 类使方法更具限制性,如果我将它的方法设为 public,就不会出现编译错误。
  • 感谢您的澄清。
猜你喜欢
  • 1970-01-01
  • 2011-11-20
  • 2011-09-16
  • 2019-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
相关资源
最近更新 更多