będę znowu zmieniać nazwy klas, tak, że wszystko jest bardziej czytelne. Więc zróbmy:
public class First<T extends Second, U extends First<T, U>> {
Third<T, U> c;
void test() {
c.acceptParameterOfTypeA(this);
}
}
class Second {
}
public class Third<X extends Second, Y extends First<X, Y>> {
void acceptParameterOfTypeA(Y a) {
}
}
Z definicji członka c
(Third<T, U>
), możemy stwierdzić, że c
narazi metodę z tym podpisem:
void acceptParameterOfTypeA(U a) { .. }
Co jest U
? U
jest podtypem First<T, U>
.
Ale jeśli U
można podstawić First
po typu skasowaniem, będzie to oznaczać, że First extends First<T, First>
, co nie jest prawdą, ponieważ U
oznacza podtypu First
, który jest parametryzowane z pewnych konkretnych podtypów Second
i First
.
Aby dostać się do U
, można zastosować tzw Get This
podejście.
Po pierwsze, ponieważ trzeba U
, który jest podtypem First
, ale nie może uzyskać go od First
można wprowadzić metodę, która zwraca abstract
go:
abstract class First<T extends Second, U extends First<T, U>> {
Third<T, U> c;
void test() {
c.acceptParameterOfTypeA(getU());
}
abstract U getU();
}
Następnie zaimplementować próbkę podklasa First
zwany Fourth
, która rozciąga First
z konkretne typy do T
i U
, na przykład:
class Fourth extends First<Second, Fourth> {
Fourth getU() {
return this;
}
}
W metodzie getU()
po prostu wykonaj return this;
, ponieważ zwróci ona prawidłowy zamiennik U
w super-klasie.
Więcej informacji:
'klasa B {' tam, parametr 'A' wygląda na surowo. –
EpicPandaForce
@EpicPandaForce tak, myślę, że mam zły przykład. Spróbuję sprawdzić, czy mogę poprawić. Dzięki! –
@EpicPandaForce dzięki, zaktualizowałem pytanie z faktycznym scenariuszem, z którym stoję. –