2013-03-27 8 views
8

Próbuję dowiedzieć się, jak uzyskać generics, aby przeskoczyć przez obręcze.Generics Puzzler

mam:

interface Root { } 
interface Middle extends Root { } 
class Type implements Root { } 

I wiele "podtyp" klas:

class Subtype1 extends Type implements Middle { } 
class Subtype2 extends Type implements Middle { } 
... 

Co chcę jest zadeklarować klasę z dwoma parametrami typu T i S, gdzie T jest związane Type i S jest związany przez T i Middle.

Nie widzę sposobu na generyczne, aby zapewnić, że S rozszerza się o T I implementuje Middle. Co chcę jest coś takiego:

class Handler<T extends Root, S extends T, S extends Middle>; 

lub

class Handler<T extends Root, S extends <T extends Middle>>; 

Ale oczywiście nie są legalne. Może brakuje mi magii?

+2

Nie możesz tego zrobić. Możesz mieć wiele ograniczeń, ale muszą to być 0-1 Klasa plus wiele interfejsów. Nie możesz mieć typu ogólnego w sytuacji z wieloma powiązaniami. Podejrzewam, że to ograniczenie zostało zachowane, ponieważ pozwalanie na wpisanie wielu ograniczeń spowodowałoby wiele komplikacji w sprawdzaniu składni, co jest rzadkim przypadkiem. – BevynQ

+2

powiązane: http://stackoverflow.com/a/13261667/697449 –

+0

Dzięki. To była też moja lektura, ale doszedłem do wniosku, że możliwe jest, że czegoś mi brakuje w specyfikacji. To jest Casts! –

Odpowiedz

2

Spróbuj wprowadzić klasę abstrakcyjną, która rozszerza SubType i implementuje Middle, więc jej typ może być użyty w Handler.

abstract class MiddleSubtype extends Subtype implements Middle { } 

Następnie

class Handler<T extends Root, S extends MiddleSubtype> { //... 

EDIT: Po aktualizacji na pytanie, ta sama idea wyglądałby następująco:

abstract class MiddleType extends Type implements Middle { } 

class Subtype1 extends MiddleType { } 
class Subtype2 extends MiddleType { } 
... 

class Handler<T extends Root, S extends MiddleType> { //... 
+1

Należy zauważyć, że różni się to od 'T extends Root, S extends T ...', ponieważ 'S' nie jest już związany przez' T'. –

+0

Tak i wiąże Handler z jednym podtypem. Właściwie mam kilka podtypów, które oznaczałyby również grupę Handlerów, czego dokładnie próbowałem uniknąć. –

+0

@NickPalmer Zobacz moją edycję tej odpowiedzi - Myślę, że jest blisko tego, co sugerował rgettman. –

0

Albo można zrobić S generic się:

interface SInt<A,B> {} 
class Handler<T extends Root, S extends SInt<T, Middle>>{}