2009-04-05 13 views
1

構成とオブジェクトの方向に関する質問Javaの構成に関する質問

クラス(Java TreeMapの例)を実装する際に、もっと多くの機能を実装しようとしています。組成物を用いて

public class TreeMap<K,V> 
    extends AbstractMap<K,V> 
    implements NavigableMap<K,V>, Cloneable, Serializable 

way to go on thisあるので、私は同時に は、それができるように、それだけでそれを行う作りながら、最初のクラスの機能をラップします 再利用可能なフォワーディングクラスを作成する必要があります将来他の場所で使用することができます。 TreeMapのは 私の中で私は必要な細かな機能の数が含まれている場合はどうなります

public class BetterTreeMap<K,V> extends ForwardingNavigableMap<K,V> 
{ 
/* some new cool features here */ 
} 

public class ForwardingNavigableMap<K,V> implements NavigableMap<K,V> 
{ 
... 
} 

私はそのようにのように、新しく作成された reusable forwarding classを継承するラッパークラスを作成して進行しますNavigableMapインターフェイスの一部ではない可能性があります。私は TreeMapのための自分のインターフェイスを宣言し、私の​​再利用可能なクラスでそれを実装する必要がありますか?ここの入力は感謝しています。

答えて

1

最も簡単な方法は、単に既存のクラス

public class MyTreeMap<K,V> extends TreeMap<K,V> { 
    // add your overridden or extra methods here. 
} 

を拡張することである私は、あなたは彼らが必要以上に物事をより複雑にしない示唆しています。

これが適切でない場合は、おそらく達成しようとしていることを説明することができます。

+0

私は単純なゲームで衝突検出のためのオブジェクト境界階層を作成しようとしています。私はTreeMapが私の望むものであるかどうか分からないので、後でそれを置き換えることができる必要があります。なぜなら、継承(継承)よりも構図の優先度が高い理由は、 – Andreas

+0

構図は、基礎となるMapのタイプを動的に変更できます。継承には、それを変更するために再コンパイルが必要です。これをやりたい場合は、コードを再コンパイルすることがどれほど難しいでしょうか? –

1

これらの新機能が他のデータ構造に実装される場合は、絶対に使用してください。

そうでない場合は、無用なインターフェイスでクラスをオーバーロードしないようにしてください。混乱を最小限に抑えます。

1

ここで問題となるのは、TreeMapがインターフェイスのように動作していることです。すべてのメソッドをオーバーライドして転送することで、そのように扱うことができます。空の中に多くの状態があるようにはありませんTreeMapしかし、それは新しいメソッド(またはあなたが逃したもの)が処理されないため、脆弱なアプローチです。

あなたのクラスはおそらくMapである必要はありません。コードに適したインターフェイスを作成できますが、ライブラリと非特定コードでの使用にはasMap/asSortedMap/asNavigableMapを使用することができます。

1

どうすればよいですか?TreeMapには、クラスに必要な数多くの高度な機能が含まれていれば、NavigableMapインターフェイスの一部ではないかもしれませんか?

これは、このような場合に組成を使用する際の問題です。 TreeMapで同じメソッドを呼び出すだけの何もしないラッパーメソッドをたくさん作っているのであれば、それは継承に有利な引数です。あなたは

public Set<K> keySet() 
{ 
    return myTreeMap.keySet(); 
} 

のように見える方法のかなりの数を持っているのであれば、あなただけの、あなたが変更したいものをオーバーライドし、自由のためにそのメソッドのすべてを取得するにはTreeSetのを拡張することもできます。

が内部的ににTreeMapを使用しており、クライアントプログラムがそのことについて知る必要がない場合は、構図を使用する必要があります。クラスが追加または変更された機能がいくつかある TreeMapの場合、継承を使用します。

2

これをpulic APIにするつもりがないと仮定すると(つまり、サードパーティに出荷されておらず、そのAPIを使用することを期待しているわけではありません)、次のことができます。

TreeMap固有のメソッドへのアクセスが必要な場合、TreeMapであるクラスに依存するコードを記述しない限り、継承をTreeMap以外のものに変更することもできます(例えば、TreeMapを "extends TreeMap"とは別に参照しないでください)、あなたはextendを使って安全です。これには、TreeMapメソッドを提供するインターフェイスを記述する必要があります。

TreeMapを訴えたくない場合は、後で別のものを使用したいと思う場合は、TreeMapをどこにでも参照することはできません。次に、TreeMap固有のメソッドへのすべての呼び出しが残されます。それらのすべてが同時にTreeMapから継承されなくなると同時に消えてしまえば、あなたはうまくいきます。そうでない場合は、必要なメソッドの実装に独自の記述をする必要があります。

TreeMapから変更した場合は、作成したインターフェースにすべてのメソッドをコメントアウトして、空のインターフェースでコードをコンパイルするといいでしょう不足しているメソッドをインタフェースに追加する必要があります。あなたが拡張しようとしているクラスが、あなたがやるべきことがある欠けているメソッドを提供していない場合、またはTreeMapから拡張する必要がある場合。

代替ソリューションは、実際にTreeMapが必要かどうかを事前に把握することです。私は、私が自分のデータ構造のために必要としているものがわからないプロジェクトに行きたいとは思っていません。

1

新しいインターフェイスに新しいメソッドをすべて置き、このインターフェイスも実装するクラスを作成します。

ここでは、あなたは、このクラスが希望クラスを拡張してみましょうことができますが、あなたがしてのみを公開するように私はそれがより良いクラスのTreeMapのものでマイマップのプライベートメンバを持って検討する

public class MyMap implements MyInterface, NavigableMap { 
... 
} 

だろうあなたが実際に望むメソッドではなく、TreeMapが持っているメソッドのすべてではありません。

転送方法を書くには多くの作業が必要ですが、 Eclipseには良いリファクタリングがあり、自動的に生成することができます。