2011-01-07 6 views
0

は、関連するクラスやメソッドです:サブクラス化によって、クラスのインターフェイス実装が停止しますか?ここ

public class BoardTile implements BoardCoordinate 

public class WordPath extends LinkedList<BoardTile> 

public void inputCoordinates(Collection<BoardCoordinate> coords) 

は基本的に、何ここで起こっていることはこれです:私はフラッシュゲームのためのボットを書いている、と私は上の場所を表すためにBoardCoordinateと呼ばれるインタフェースを持っていますボード。ボード上のタイルを表すクラスはBoardTileと呼ばれ、その位置を知っているので、BoardCoordinateインターフェイスを実装します。

私はボード上のパスを表すタイルのリストを持っています。実際にはBoardTilesのLinkedListです。最後に、BoardCoordinatesのコレクションをjava.awt.Robotに渡し、要求されたパスをフラッシュゲームに渡すメソッドがあります。コレクションはスクリーンスクレーパークラスと私のデータ処理パッケージの間の潜在的な醜い結合を避けるためにパスされます。

それでは、ここで問題のコードは次のとおりです。

/* The highest scoring path found. */ 
Wordpath highest = null; 
/* ... 
* ... find the highest scoring path, etc. 
*/ 
if (longest != null) { 
    screen.inputCoordinates(longest); 
} 

私が取得コンパイラエラーがこれです:メソッドinputCoordinates(コレクション)タイプのスクリーンには、引数(WordPath)には適用されません。

しかしWordPathはBoardCoordinateのLinkedListです!そしてLinkedListはコレクションです!何が起きてる?

はもちろん、私は、LinkedList<BoardTile>はしかしCollection<BoardCoordinate>ではありません...

+0

あなたの質問には答えられませんが、デザインやクラスの名前付けに少し変更を加えることをお勧めします。 BoardTileはあなたがゲームマップやゲームボード上に置いている(または持っている)ものですが、そのようなタイルは座標ではありません**その座標は**座標です。 "現実の世界"のプロパティ。あなたが自分のコード(個人的な経験を理解しようとするか、 )または一度あなたのデザイン(別の個人的な経験;-)を伝える必要があるあなたの場合は、私は構図にデザインを変更するだろう。私は –

答えて

3

を弾丸をかむとのカップリングを受け入れるが、これは、私は、第二に、学習の機会をしたいと何まずないでき一般的な分散のために。たとえば、考えてみます。

OtherBoardCoordinateBoardCoordinateなく BoardTileある
collection.add(new OtherBoardCoordinate()); 

。リンクされたリストにそれらのうちの1つを望んでいないでしょうか?

inputCoordinates場合のみに、このようなその署名変更、コレクションからを読む必要があります。

public void inputCoordinates(Collection<? extends BoardCoordinate> coords) 

基本的には、「引数はBoardCoordinateを拡張し、いくつかの型のコレクションである必要がありますと言うが、私はそのタイプが何であるかはまったく気にしない」 inputCoordinatesの中にコレクションにアイテムを追加することはできません。最初に述べた問題の種類を防ぐことができます。

詳しくはAngelika Langer's Java Generics FAQを参照してください(「ワイルドカード」を参照)。

代替はWordPathがそれにBoardTile値を追加するが起こるの代わりにLinkedList<BoardCoordinate>を拡張し、ちょうどようにすることです。 (あなたは間違いなく多分それはしかし、あなたの場合は適切なのです。私はめったにコレクションクラスを拡張する自分自身を見つけていない?方法により、LinkedListを拡張する必要があります。)

+0

しかし、他のBoardTileはBoardCoordinateを実装せずにどのようにBoardTileになれますか?親のメソッドを継承しないため、BoardCoordinateを実装していますか? – Alex

+0

@Alex:申し訳ありませんが、私はそれが間違った方法ラウンドを持っていた。 BoardTileでないOtherBoardCoordinateでなければなりません。 –

0
class B extends A { ... } 

Collection<A> collectionA; 
List<A> listA; 
List<B> listB; 

listA = listB; // error 

collectionA = listB; // error 

でもB extends Aかかわらず、List<B>ませですList<A>のサブクラスです。 List<B>Collection<A>のサブクラスではありません。

最初は直感的でした。それについて考えるための方法がある:あなたが上記の例ではList<A>の代わりにCollection<A>を置き換える場合

List<A> listA; 
// This declaration means that listA promises to point to a List that 
// accepts any instance of 'A' or subclasses of 'A' 

List<A> listA = new List<A>(); 
listA.add(new A()); 
// this is legal because listA promises to put to lists that accept 'A's 

List<B> listB = new List<B>(); 
// new List<B>() creates a list that can hold only instances 
// of 'B' or subclasses of 'B' 

listA = listB; 
// error - broken promise - allowing this assignment would means listA 
// will now point to a list that will *NOT* accept an 'A', in direct 
// conflict with what is promised by its listA's declaration 

listA.add(new A()); 
// if the above assignment were allowed, then this line would allow 
// an `A` to be added to a list that can only hold `B`s 

void myMethod(List<A> listA) { } 

myMethod(listB); 
// error - broken promise - allowing this parameter would means listA 
// (in myMethod) will now point to a list that will *NOT* accept an 'A', 
// in direct conflict with what is promised by its listA's declaration 

同じ議論が成り立ちます。


はいえ可能な解決策があります。

screenは、コレクションcoordsから読み込みます、その後、ワイルドカードを使用して作業する必要がある場合:

public void inputCoordinates(Collection<? extends BoardCoordinate> coords) 

inputCoordinateList<BoardTile>引数を受け付けます。

しかし、キャッチがあります。 inputCoordinatecoordsから読み取ることができます。より一般的には? extends XXXのために、型パラメータを返すメソッド(例えばXXX get(...))を呼び出すことができますが、メソッドパラメータの型として型パラメータを使用するメソッドを呼び出すことはできません(例:void add(XXX arg)

関連する問題