2009-04-08 11 views
5

私は抽象getType()メソッドを持つ基本クラスを持っています。私は、サブクラスがこのメソッドを実装し、実際のクラスを使用できるようにしたいと考えています。コードでJavaでネストされたクラス型を返します。

、次のようなもの:

public abstract class A { 
    public static interface Tile; 

    protected abstract Class<Tile> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected abstract Class<A.Tile> getTileClass() { 
     MyTile t = new MyTile(); // WORKS 
     return MyTile;   // ERROR HERE 
    } 
} 

ここでの問題は、私はマークされた行に「MyTileは解決できない」を得るということです。 getClass()

リターン新しいMyTile()が、今のEclipseは私に伝えます::。だから私は、この代わりを返すようにしようとしている

型の不一致を: から変換することはできませんクラス<キャプチャ#1? B.MyTile > は、クラス<私は多分ここにEclipseのバグのトップがあります場合でも、わからない

A.Tile >まで伸び(キャプチャ#1?)。

次に、私はインターフェイスをあきらめ、抽象ベースのTileクラスを使用しようとしています。だから私は基本的に3つの質問持っているように見える

public abstract class A { 
    public static abstract class Tile; 

    protected abstract Class<? extends Tile> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile exends A.Tile { } 

    @Override 
    protected abstract Class<? extends A.Tile> getTileClass() { 
     return new MyTile().getClass(); // WORKS 
     return MyTile;     // "Cannot be resolved" 
    } 
} 

:Eclipseのからいくつかの助けを借りて、私はコンパイルすると思われる次のコードで終わる)

1を、これはAで動作するように取得することが可能です.Tileはインターフェースですか?

2)基本クラスを使用する場合、実際にはClass<? extends X>は正しい方法ですか?

3)メソッド内から入れ子になったB.MyTileクラス参照をどのように戻すことができますか? new MyTile().getClass()しなければならないことは正しいことができますか?

+0

おそらく、非反射オブジェクトの代わりに 'Class'を返すのは悪い考えです。 –

+0

@Tomチェックされた型の文脈でクラスを返すことは非常に一般的なパターンであり、実行時にコレクションの* checked *型をチェックすることができます。私は実際には他の方法は知りません... – Varkhan

答えて

6

ジェネリック型と共変型のオーバーライドはあまりうまく機能しません。あなたは明示的にgetTileClass()を、サブクラスのA.Tileになるクラスを返すものとして宣言しなければなりません。

MyTileのクラスオブジェクトには、MyTile.classを使用してインスタンス化することなくアクセスできます。

は、代わりにこれを試してみてください:

public abstract class A { 
    public static interface Tile; 

    protected abstract Class<? extends Tile> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected Class<MyTile> getTileClass() { 
     return MyTile.class; 
    } 
} 

さらに良いことには、汎用的にするだろう。あなたはまだを使用する必要がクラス型定義でを拡張しませんが、もう少し具体的にすることができます

public abstract class A<T extends A.Tile> { 
    public static interface Tile; 

    protected abstract Class<? extends T> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected Class<MyTile> getTileClass() { 
     return MyTile.class; 
    } 
} 
+0

おそらくコピー&ペーストエラーですが、抽象メソッドには本体がありますか?正しい "保護する必要がありますクラス getTileClass {..." –

+0

@カロスはい、それは卵子のc/p – Varkhan

+0

良い答えです。共分散や一般的な理由から、これは問題ですか? – Uri

-1
public abstract class A { 
    public static interface Tile {}; 

    // I return something that is-a Tile 
    protected abstract Tile getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected abstract Tile getTileClass() { 
     return new MyTile(); 
    } 
} 

ジェネリック医薬品のための必要性を全く、あなたはちょうどあなたがタイルやタイルを返すことを言いたいですサブクラス。

なお、クラス内のpublic staticインターフェイスは「コードの匂い」です。それを保護するか、AのサブクラスだけがTileを実装するか、それを独自の最上位インタフェースに入れてください。誰かがそれを実装できるようにするが、混合メッセージを送信する。

関連する問題