2013-03-27 16 views
8

私は、ジェネリックスがどのようにしてフープを飛び越すのか把握しようとしています。Generics Puzzler

私が持っている:

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

そして、多くの "サブタイプ" クラス:私が欲しいもの

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

TTypeにより拘束された2種類のパラメータTS、持つクラスを宣言することですSは、TMiddleで結ばれています。

STに拡張され、Middleが実装されていることを確認する方法が表示されません。私が欲しいもの のようなものです:

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

または

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

しかし、もちろん合法的でもありません。多分私は行方不明の魔法がありますか?

+2

これはできません。複数の境界を持つことはできますが、それらは0-1クラスと複数のインタフェースを加えなければなりません。複数のバインドされた状況では、汎用型を持つことはできません。私はこの種の制限が残っていると考えています。なぜなら、複数の境界で型を許可すると、まれなケースであるため、シンタックスチェッカーに多くの複雑さが生じるからです。 – BevynQ

+2

関連:http://stackoverflow.com/a/13261667/697449 –

+0

ありがとうございます。それも私の読書でしたが、私は仕様で何かを見逃していた可能性が考えられた。それはキャストです! –

答えて

2

SubTypeに拡張され、Middleを実装する抽象クラスを導入してください。そのタイプはHandlerで使用できます。その後

abstract class MiddleSubtype extends Subtype implements Middle { } 

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

はEDIT:質問への更新後、同じ考え方は次のようになります。

abstract class MiddleType extends Type implements Middle { } 

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

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

これは 'Sは' Tによってもはや束縛されていないので、 'T extends Root、S extends T ... 'とは異なることに注意してください。 –

+0

はい、Handlerを1つのサブタイプに結び付けます。私は実際に私が避けようとしていたハンドラーの束を意味するサブタイプの束を持っています。 –

+0

@NickPalmerこの回答を編集してください - これはrgettmanが提案していたものに近いと思います。 –

0

それとも、Sジェネリック自体を作ることができる:

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