【问题标题】:Call default method from other interface in another default method在另一个默认方法中从其他接口调用默认方法
【发布时间】:2019-03-03 08:44:09
【问题描述】:

此代码崩溃:

public class MyClass {
    public static void main(String args[]) {
      Person person = new Person();
      person.selectMe();
    }
}

class Entity {}

interface EntityNameable<T extends Entity> {
  default String getSomething() {
    return "";
  } 
}

interface EntityNameableSelectable<T extends EntityNameable> {
  default String selectMe() { 
    return ((EntityNameable) this).getSomething();
  } 
}

class Person extends Entity implements EntityNameableSelectable {

}

这段代码可以通过复制粘贴到https://www.jdoodle.com/online-java-compiler来执行

Exception in thread "main" java.lang.ClassCastException: Person cannot be cast to EntityNameable
    at EntityNameableSelectable.selectMe(MyClass.java:18)
    at MyClass.main(MyClass.java:4)

它崩溃是因为 person 不能转换为 EntityNameable。为什么不? person 始终是 EntityEntityNamableEntityNameableSelectable 对吧?

我也想知道为什么我需要将它转换为EntityNameable 来调用方法getSomething,因为每个实现类都应该有那个方法。为什么需要演员表?它必须与崩溃有关...

【问题讨论】:

    标签: java inheritance interface java-8 default-method


    【解决方案1】:

    我也想知道为什么我需要将它转换为 EntityNameable 来调用方法 getSomething,因为每个实现类都应该有这个方法。

    EntityNameableSelectable 不是EntityNameableEntityNameableSelectable 没有扩展该接口,因此没有方法被继承。

    您可能希望EntityNameableSelectable 扩展EntityNameable,这样您就可以调用getSomething()

    interface EntityNameableSelectable<T extends Entity> extends EntityNameable<T> {
        default String selectMe() {
            return getSomething();
        }
    }
    

    Person 始终是 EntityEntityNamableEntityNameableSelectable,对吧?

    仅当EntityNameableSelectable 扩展EntityNameablePerson 实现EntityNameable

    如果您如上所述定义了EntityNameableSelectablePerson 类将如下所示:

    class Person extends Entity implements EntityNameableSelectable<Person> {}
    

    【讨论】:

      【解决方案2】:

      Person 始终是 EntityEntityNamableEntityNameableSelectable 对吧?

      Person 扩展了Entity 并实现了EntityNameableSelectable,但它没有实现EntityNameable,没有。

      我不知道你到底想做什么,但我怀疑&lt;T extends EntityNameable&gt; 没有做你想做的事。尝试让EntityNameableSelectable 扩展EntityNameable

      interface EntityNameableSelectable extends EntityNameable {
        default String selectMe() { 
          return getSomething();
        } 
      }
      

      同样,使EntityNameable 具有通用T 参数也可能不正确。在您的示例代码中,T 没有做任何事情,因此您可以将其删除。

      interface EntityNameable {
        default String getSomething() {
          return "";
        } 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-28
        • 2018-06-13
        • 2018-08-28
        • 1970-01-01
        • 2015-04-27
        • 2019-01-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多