2011-12-26 20 views
1

C#のように "instanceof"を使わずにforループで多形性をどう扱うことができるのだろうかと思っていました。ここ は、私が持っているものです。Java forループとポリモーフィズム

抽象クラスA:Aを拡張しての抽象メソッドを実装し

public abstract class A 
{ 
    public abstract Map<Long, ? extends A> getNodes(); 
    public abstract void setNodes(Map<Long, ? extends A> n); 
} 

BとCクラス:

public class B 
{ 
    private Map<Long, C> childNodesC; 

    @Override 
    public Map<Long, ? extends A> getNodes() 
    { 
     return childNodesC; 
    } 

    @Override 
    public void setNodes(Map<Long, ? extends A> n) 
    { 
     for(C child : n) 
      childNodesC.put(child.getId(), child); 
    } 
} 

は、forループのようなものですこれはJavaでsetNodes()メソッドで可能ですか?つまり、私のループでは、Aオブジェクト(ここではBまたはCオブジェクトのいずれか)のリスト内のすべてのCオブジェクトに対してのみ繰り返したいとJavaが理解する方法があります。

それとも私はそのような正しい方法か何かで多型を使用していない...または多分これは「instanceofの」オペレータの使用状況の真のケースです:)

(うんあなたは正しい、私は"instanceof"演算子が好きではないと思うので、正しく処理していないと思うので、キャストとインスタンスを修正する必要があります。それは私には「汚い」と思われますが、間違っているかもしれません。 )それは非常に一般的です!)

ありがとう!

+0

'instanceof'を使うのはちょっと間違っています。しかし、私はここでデザイン全体がちょっと間違っていると思う:Bの 'setNodes(nodes)'が実際に与えられたノードのいくつかを無視することは、ユーザにはっきりしない。 – toto2

答えて

2

インスタンスがどのサブクラスであるかを知る必要がある場合があります。あなたのケースがそれらの1つであるかどうかは、実際には判断できません。しかし、これを実装する必要がある場合は、Visitor Patternの使用を検討し、必要なサブクラスのメソッドのみを実装する必要があります。このようにして、「汚れた」インスタンスチェックを回避します。

0

Javaでは(少なくともJava 6では)この種の構造は可能ではありません。そのループは、すべてのオブジェクトがCのインスタンスであると予想し、フィルタとして動作しません(そうでなければなりません)。一般的に、あなたが何かをループしているなら、あなたはすべてを得たいと思う。さらにフィルタリングしたい場合は、別のアクションです。 instanceofを使用することには恥ずべきことはありません(オブジェクトのプロパティをチェックするのは残念です)。

1

Javaではこのようなループフィルタは使用できません。多相性を正しく使用しているかどうかは、もう少し文脈がなければ言い難いです。 B.childNodesCAで利用できない方法を使用する必要がある場合は、instanceofを使用してCを除外する必要があります。しかし、より純粋にOOのアプローチは、Aにいくつかのフィルタリングの質問に答えるメソッドを定義し、次にBのマップにAの値を持たせることです。ような何か:

A.isSomethingInteresting() -> false 
A.doSomething() { ... } 
C.isSomethingInteresting() -> true 
C.doSomething() overrides { ... } 

B.setNodes、各Aは、何か面白いものであるかどうかを確認し、それがない場合にのみ、そのマップに追加します。その後、AのそれぞれでdoSomething()が呼び出され、多態性がそこから取り込まれます。

+1

Downvoter、理由を与えるために気をつけてください? – yshavit