2009-05-29 8 views
21

私が持っているifでテストを実行するための最良の方法は何ですかなど、WhereStatementIfStatementという名前のいくつかの他のクラスから継承する基底クラス、Statement、...どのような種類のインスタンスが由来するStatementクラスを決定するステートメント?ないJavaが持っている試験方法「クラスの一種である」

答えて

53
if (obj.getClass().isInstance(Statement.class)) { 
    doStuffWithStatements((Statement) obj)); 
} 

このテクニック(「instanceof」キーワードとは対照的に)には、テストクラスをオブジェクトとして渡すことができます。しかし、ええ、それ以外は、 "instanceof"と同じです。

注:タイプインスタンスのチェックがの右ののものかどうかについて、私は意図的に編集を避けました。ええ、ほとんどの場合、多型を使用する方が良いです。しかし、それはOPが尋ねたものではなく、私は彼の質問に答えるだけです。

+3

単純なinstanceofチェックを使用するだけではどうですか? –

+5

instanceofはgotoのように邪悪ではありません。言語に追加された理由と、その言語が非推奨になっていない理由があります。 –

+10

+1は「タイプインスタンスのチェックが正しいことかどうかについて編集しない」ため –

64
if(object instanceof WhereStatement) { 
    WhereStatement where = (WhereStatement) object; 
    doSomething(where); 
} 

このようなコードは、通常、基本クラスに多型メソッドがないことに注意してください。すなわちdoSomething()は、サブクラスによってオーバーライドされるStatement(おそらく抽象的な)のメソッドである必要があります。

+0

追加情報ありがとう!私はそれを見て、デザインを改善するきれいな方法があるかどうかを見ていきます。 –

+5

+1と答えましたが、 'instanceof'には有効な使い方がたくさんあります。これはいつもデザインの匂いではありません。たとえば、 'doSomething()'がwhere節にのみ適用可能ならば、このパターンはおそらくStatementクラスの 'doSomething()'を人工的に作るよりも優れているでしょう(論理的には適合しません)。 – mikera

+0

'instanceof'が役に立つ別の例です。 JavaFXでは、ペインがあります。私は子ノードのツリーを横断する必要があります。 'getChildren()'はノードを返します。しかし、ノードの1つがペインである場合、私は_its_子もトラバースする必要があります。 Nodeは 'getChildren()'メソッドを持たず、それを追加するためのものでもありません。ですから、ノードをペインにキャストしてその子をトラバースする必要があるかどうかを確認するには、 'node instanceof Pane'を使用する必要があります。 – dwilliss

6

あなたの質問に対する答えはinstanceofです。

しかし、あなたのコードがinstanceofの必要がある場合、それは何かがあなたのデザインの権利ではない兆候だということを覚えておいてください。 instanceofが正当化される場合もあるが、むしろ例外である。通常、あなたのサブクラスが異なる振る舞いをする必要がある場合は、if()の代わりに多態性を使用する必要があります。

+0

私があなたの推薦に追加する唯一のことは、インターフェイスによるプログラミングの強力な提案です。 – monksy

0

これはではありません。オブジェクト指向の方法を行う方法です。これは古いコード/データの二分法の後戻りです。今(あなたは何をやっている知っていれば)、それは必ずしも悪いことではないのですが、それは適切な設計によりC.

のような非オブジェクト指向言語に委ねられるべき、あなたは行動の並べ替えをする必要はありません。代わりに、コンストラクトの:次に

obj.doStuff(); 

それぞれ異なるobj

if (obj.getClass().isInstance(Statement.class)) { 
    doStuffWithStatements((Statement) obj)); 
} 

(謝罪は、彼のコードを「盗む」のbenjismithする)、あなたは本当にため、自身の活動のためのオブジェクト自体は責任を作るべきですクラスにはdoStuffの独自の定義があります。それが正しい方法です。クラスから

+0

サブクラスだけがdoStuff(™paxdiabio)を実行でき、サブクラスのスーパークラスであるオブジェクトの配列を持っている場合は、これを行うより良い方法です(no-op'dを追加するのではなく) doStuffメソッドを無意味な(または「ちょうど間違っている」)スーパークラスに変換します。 – geowar

+0

@geowar、非同質のもののコレクションを持っているなら、それらはおそらくコレクション内にあってはいけません。または、少なくとも、あなたは、そのコレクションをdoStuffにしたいと思うように繰り返すべきではありません。これを処理する方法はいろいろありますが、クラス名や型に結びつけることは変更を加えるときに非常に問題になります。継承/オブジェクト指向の世界では、このケースで何もしたくないスーパークラスのnull関数を持つことは、実際には有効な解決策であり、処理コードをもっときれいにします。 – paxdiablo

1

これを試してください:

if (Statement.class.isInstance(obj)) { 
    doStuffWithStatements((Statement) obj)); 
} 

Class.isInstance()のでメソッドは、パラメータとしてオブジェクト・インスタンスを取ります。

関連する問題