Подтвердить что ты не робот

Интерфейсы Java и типы возврата

У меня есть следующий интерфейс:

public interface A { public void b(); }

Однако я хочу, чтобы каждый из классов, которые его реализовали, имел другой тип возврата для метода b().

Примеры:

public class C { 
  public C b() {} 
}

public class D { 
  public D b() {} 
}

Как я могу определить свой интерфейс, чтобы это было возможно?

4b9b3361

Ответ 1

Если тип возвращаемого типа должен быть типом класса, который реализует интерфейс, то то, что вы хотите, называется F-ограниченным типом:

public interface A<T extends A<T>>{ public T b(); }

public class C implements A<C>{
  public C b() { ... }
}

public class D implements A<D>{
  public D b() { ... }
}

В словах A объявляется параметр типа T, который будет принимать значение каждого конкретного типа, реализующего A. Обычно это используется для объявления таких вещей, как методы clone() или copy(), которые хорошо типизированы. В качестве другого примера он использовал java.lang.Enum, чтобы объявить, что каждый enum, наследуемый метод compareTo(E) применяется только к другим перечислениям этого конкретного типа.

Если вы используете этот шаблон достаточно часто, вы столкнетесь с сценариями, где вам нужно this быть типа T. На первый взгляд может показаться очевидным, что это 1 но вам действительно нужно объявить метод abstract T getThis(), который разработчикам придется тривиально реализовать как return this.

[1] Как отмечают комментаторы, можно сделать что-то скрытое, как X implements A<Y>, если X и Y взаимодействовать должным образом. Наличие метода T getThis() еще более ясно показывает, что X обходит намерения автора интерфейса A.

Ответ 2

Дженерики.

public interface A<E>{
    public E b();
}

public class C implements A<C>{
    public C b(){
        return new C();
    }
}

public class D implements A<D>{
    public D b(){
        return new D();
    }
}

Искать общие сведения для получения более подробной информации, но (очень) в основном, что происходит в том, что A оставляет E до тех пор, пока они не будут реализованы (C и D).

Таким образом, в основном A не знает (и не должен знать), что E может быть в любой конкретной реализации.