0

私はJavaでインベントリプログラムに取り組んでいます。DefaultListModelインベントリ内の各オブジェクトを、場所ごとに関連するクラスタイプとして保存していJListます。たとえば、「Mulan」という動画と「Dorm」という場所に「Ball」という一般的なものがある場合、「Dorm」という場所ではJList「Mulan」がインスタンスにvideoなり、「Ball」がインスタンスになります。のthing。すべてのクラスはThingから継承されます。

私はこのようなことをしようとしています...

Dorm.getSelectedValue().methodInVideoOrThing;

...しかし、私がそれを試してみると、それは言います:

error: cannot find symbol
      Dorm.getSelectedValue().methodInVideoOrThing();
                             ^
symbol:   method methodInVideoOrThing()
location: class Object

DefaultListModelは各オブジェクトをジェネリックobject変数に格納するため、作成したクラスのメソッドにアクセスできません。私はこれを試しました...

class c = Dorm.getSelectedValue().getClass();
c A = (c) Dorm.getSelectedValue();
A.methodInC;

...しかし、次のエラーが返されました。

error: cannot find symbol
      c A = (c) Dorm.getSelectedValue();
      ^
symbol: class c

error: cannot find symbol
      c A = (c) Dorm.getSelectedValue();
             ^
2 errors
symbol: class c

isInstanceOfケースバイケースでダウンキャストを使用してすべてのクラスを循環できることはわかっていますが、それは非常に面倒です。さらに、私がするとき...

System.out.println(Dorm.getSelectedValue().getClass());

class video...「Ball」または「Mulan」のどちらが選択されているかに応じて、またはのいずれかが返されるclass thingため、Javaはそれがどのクラスであるかを認識していることがわかります。

それで、サブクラスがオブジェクト型の変数として格納されているときに、ダウンキャストせずにサブクラスのメソッドにアクセスできる方法はありますか?または、ダウンキャストでこれを行う方法はありますか?私はそれを間違っていますか?

4

2 に答える 2

0

ここでの問題は、オブジェクト指向の設計にあります。「methodInVideoOrThing()」とはどのようなメソッドですか?これがすべてのもの(ビデオを含む)に共通する方法である場合、それはThingに属します。それがビデオ固有のメソッドである場合、それはビデオに属します。

最初のケース(Thingのメソッド)では、JListからThingに値をキャストするだけで、完了です。

Thing selectedThing = (Thing) dorm.getSelectedValue();
selectedThing.methodInThing();

2番目のケース(ビデオの方法)では、ビデオ、果物、衣類などのさまざまなカテゴリを区別する必要があるという問題があります。この場合、私が行うと思うのは、各カテゴリを処理するための個別のクラスを作成し、そのカテゴリに基づいてオブジェクトをそれに渡すことです。簡単な例です。

public interface Handler {
    public Class getCategory();
    public void handle(Thing item);
}

public class VideoHandler implements Handler {
    public Class getCategory() {
        return Video.class;
    }

    public void handle(Thing item) {
        if (!item instanceof getCategory()) {
            throw new IllegalArgumentException("Wrong category - can only handle Video");
        }
        Video video = (Video) item;
        // do video-things            
    }        
}

呼び出し元のクラスでは、カテゴリに基づいて正しいハンドラーを選択する必要があります。

private void init() {
    List<Handler> handlers = new ArrayList<Handler>();
    handlers.add(new VideoHandler());
    // add other handlers
}

public void someMethod(Jlist dorm) { 
    Object item = dorm.getSelectedValue();
    for(Handler handler : handlers) {
        if (item instanceof handler.getCategory()) {
            // optionally catch IllegalArgumentException here 
            handler.handle(item);
        }
    }
}

これはもう少し良くすることができます。たとえば、クラスの代わりに列挙型をカテゴリとして使用し、ジェネリックスを使用してハンドラーを入力し、一般的な動作(型チェックなど)を抽象クラスに抽出しますが、これがその要点です。

于 2013-03-11T09:09:37.807 に答える
0

そのため、ダウンキャスト以外のスーパータイプからサブタイプのメソッドを使用する方法はありません。if-else はしごを設定したほうがいい

if (o instanceof Type1)
{
((Type1)0)MethodOfType1
}
else if
{
...
}

しかし、私の意見では、モノとビデオの上にもう 1 レベルのクラスを追加し、モノとビデオの汎用メソッドを提供することをお勧めします。

于 2013-03-11T07:30:07.530 に答える