2017-11-02 20 views
2

instanceof演算子を使用してクリーンコードを書くことを避けることができます 例: オブジェクトがタイプ1であれば何かしますが、タイプ2であれば何かをします。どのようにinstanceof使用を避けることができますか?

if(obj instanceof T1){ 
    doSomething() 
}else(obj instanceof T2){ 
    doOtherThing() 
} 
+0

「instanceOf」ではなく「instanceof」であることがわかりますか? [Chain of responsibility](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern)を実装することができます。チェーン内の各要素は正確に1つの 'instanceof'操作を行い、それが収まる場合はイベントを消費します。おそらく、これは[XY問題](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – Turing85

+0

のようであるため、あなたが達成しようとしていることをより詳細に説明する必要があります実際にコードが何をしているのか、あなたがコントロールしているクラス(インタフェースを抽象化できないサードパーティ製のライブラリではないかなど)などに依存します。残念ながら、問題は広すぎます。答えは一般的にはオーバーライドされたメソッドを使用しますが、詳細は異なります。 – yshavit

+0

私は個人的に 'getClass()'メソッドを好んでいます。私が実装しているロジックでは、スーパークラスではない正確なクラスを知る必要があるとします。 –

答えて

2

一般的には、クラスではなく、他に存在する特定のメソッドを呼び出すためにキャストでinstanceofのシリーズを使用します。

if(obj instanceof T1){ 
    ((T1)obj) doSomething(); 
} 
else(obj instanceof T2){ 
    ((T2)obj) doOtherThing(); 
} 

あなたはこれらのクラスを変更することができれば、それを避けるために、T1T2必要があります共通の基本クラスのサブクラスであり、呼び出されたメソッドは基本クラスで定義される必要があります。
このように、各サブクラスは、それを実装することができ、あなたはそう書くことができます:

obj.doSomething(); 

あなたはこれらのクラスを変更できない場合、あなたは常に共通の方法を提供するためにそれらをラップAdapterクラスを導入することができますこれらのメソッドを呼び出します。

アダプタ

public interface Adapter{ 
    void process(); 
} 

AdapterForT1

public class AdapterForT1 implements MyAdapter{ 

    private T1 adapted; 
    public AdapterForT1(T1 adapted){ 
     this.adapted = adapted; 
    } 

    public void process(){ 
     adapted.doSomething(); 
    } 

} 

AdapterForT2

public class AdapterForT2 implements MyAdapter{ 

    private T2 adapted; 
    public AdapterForT2(T2 adapted){ 
     this.adapted = adapted; 
    } 

    public void process(){ 
     adapted.doOtherThing(); 
    } 

} 

そして、あなたはそれらを使用することができますこの方法:

MyAdapter adapter = new AdapterForT1(obj); 
... 
adapter.process(); 

か:

MyAdapter adapter = new AdapterForT2(obj); 
... 
adapter.process(); 
1

あなたが、ここをオーバーライドメソッドを使用して、個々のクラスだから、例えば

に実装ごとに異なる命令セットを実行します異なるクラスの異なるインスタンスから同じ機能を呼び出す必要がありますあなたは

T t1 = new T1(); 
T t2 = new T2(); 

// this will execute function overridden in T1 
t1.executeTask(); 

// this will execute function overridden in T2 
t2.executeTask(); 
0、そう

executeTask機能を実装

クラスT、その後、クラスT1とT2クラスを持って、両方のクラスTおよびすべての3つのクラスを拡張します
1

は、両方のクラスが実装interfaceを作成します。インタフェースは、すべての実装クラスが遵守しなければならない契約のようなものです。

このようにすれば、そのようなクラスのすべてのインスタンスに、そのインターフェイスから実装されたすべてのメソッドが実装されていることを保証できます。

例えば

public interface CustomExecutable { 
    void execute(); 
} 

次に、あなたの二つのクラス:

public class T1 implements CustomExecutable { 
    @Override 
    public void execute() { 
     // Do t1 logic 
    } 
} 

public class T2 implements CustomExecutable { 
    @Override 
    public void execute() { 
     // Do t2 logic 
    } 
} 

あなたのメインプログラムでは、あなたがこのような何かを行うことができます:

CustomExecutable ce = new T1(); 
ce.execute(); // Does t1 logic 
ce = new T2(); 
ce.execute(); // Does t2 logic 

instanceofはもう必要ありませんなぜなら、各タイプには独自の方法があるからです。コードはexecuteです。

関連する問題