Я хочу иметь функцию, определенную в суперклассе, которая возвращает экземпляр подкласса, который используется для вызова функции. То есть, скажем, у меня есть класс A с функцией plugh. Затем я создаю подклассы B и C, которые расширяют A. Я хочу, чтобы B.plugh возвращал B, а C.plugh возвращал C. Да, они могли возвращать A, но тогда вызывающий должен был бы либо привести его вправо подтип, который вызывает боль при частом использовании или объявляет принимающую переменную как супертип, что теряет безопасность типа.
Итак, я пытался сделать это с помощью дженериков, написав что-то вроде этого:
class A<T extends A>
{
private T foo;
public T getFoo()
{
return foo;
}
}
class B extends A<B>
{
public void calcFoo()
{
foo=... whatever ...
}
}
class C extends A<C>
{
public void calcFoo()
{
foo=... whatever ...
}
}
Кажется, это работает, но выглядит довольно уродливо.
Во-первых, я получаю предупреждения class A<T extends A>
. Компилятор говорит, что A является универсальным, и я должен указать тип. Я думаю, что он хочет, чтобы я сказал class A<T extends A<x>
. Но что бы я положил на х? Я думаю, что могу застрять здесь в бесконечном цикле.
Кажется странным писать class B extends A<B>
, но это не вызывает никаких нареканий, так что, может быть, это нормально.
Это правильный способ сделать это? Есть ли лучший способ?