Вызовите метод по умолчанию из другого интерфейса в другом методе по умолчанию - PullRequest
0 голосов
/ 27 сентября 2018

Сбой этого кода:

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 всегда Entity, EntityNamable и EntityNameableSelectable верно?

Мне также интересно, почему мне нужно привести это значение к EntityNameable для вызова метода getSomething, так как каждая реализациякласс должен иметь этот метод.Зачем нужен актерский состав?Это связано с аварией ...

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

A Person всегда является Entity, EntityNamable и EntityNameableSelectable верно?

A Person расширяет Entity и реализует EntityNameableSelectable, ноон не реализует EntityNameable, нет.

Я не знаю точно, что вы пытаетесь сделать, но я подозреваю, что <T extends EntityNameable> не делает то, что вы хотите, чтобы он делал.Попробуйте вместо этого EntityNameableSelectable extension EntityNameable:

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

Аналогично, использование EntityNameable с универсальным параметром T также может быть неправильным.В вашем примере кода T ничего не делает, поэтому вы можете просто удалить его.

interface EntityNameable {
  default String getSomething() {
    return "";
  } 
}
0 голосов
/ 27 сентября 2018

Мне также интересно, почему мне нужно привести это значение к EntityNameable для вызова метода getSomething, поскольку каждый реализующий класс должен иметь этот метод.

EntityNameableSelectable не является EntityNameable,EntityNameableSelectable не расширяет этот интерфейс, поэтому никакие методы не наследуются.

Вероятно, вы хотели, чтобы EntityNameableSelectable расширил EntityNameable, поэтому вы сможете звонить getSomething().

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

A Person всегда Entity, EntityNamable и EntityNameableSelectable, верно?

Только если EntityNameableSelectable расширяется EntityNameable или Person реализует EntityNameable.

Если вы определили EntityNameableSelectable, как я упоминал выше, класс Person будет выглядеть так:

class Person extends Entity implements EntityNameableSelectable<Person> {}
...