2012-02-19 11 views
1

私は、いとこが非常に似た機能を共有するクラス階層を持っています。たとえば:有界型へのキャスト

Node 
    Statement 
    FunctionCallStatement 
    Expression 
    FunctionCallExpression 

FunctionCallStatementとFunctionCallExpressionは非常によく似たAPIを共有し、私は、単一継承階層を持つ純粋なクラスの用語ではそれを表現することはできません。だから、これらの両方が実装されているIsFunctionCallインターフェイスを作成しました。このすべてが非常にうまく動作

void <T extends Node & IsFunctionCall> doSomething(T node) { ... } 

:私は今、次のようにFunctionCallStatementまたはFunctionCallExpressionのいずれかを受け取るメソッドを宣言することができます。

残念ながら、私は今、かなり面倒な問題に直面しています。私はノードを持っています。私はそれが動的であることを知っていますはFunctionCallStatementかFunctionCallExpressionのいずれかでなければなりません。私はそのNodeを上記のdoSomething()メソッドに渡す必要があります。私はそれを適切なタイプにアップキャストする方法を見つけることができません。

今はinstanceofのチェーンを使用してNodeがどのクラスであるかを判断し、それを適切な具体的な型にキャストしていますが、それはbutt-uglyです。私がこの作業をするために知っている他の唯一の方法は、IsNodeインターフェイスを作成し、現在ノードがIsNodeを期待していることをすべて期待することです。これにより、IsNodeとIsFunctionCallを実装した共用体インタフェースを宣言し、上記のジェネリックスを使わずに済ませることができます。しかし、それはたくさんの仕事の地獄であり、まだかなり醜いです。

これを行う別の方法はありますか?

(注:上記の例では、私の実際のコードの簡略版である)更新

:次いで

@SuppressWarnings("unchecked") 
private <S extends Node & IsFunctionCall> S castNode(Node node) 
{ 
    return (S) node; 
} 

と:

doSomething(castNode(node)); 
私は悪の次のピースを試し

非常に奇妙なエラーメッセージがあります。 castNode()のSを決定するために使用される型推論は、doSomething()の宣言でTと一致しないように見えます。具体的な型だけを使用し、SをNodeに設定しています。どちらが当然doSomething()の宣言型と一致しません。非常に独特です。

更新更新:

これはHow should I cast for Java generic with multiple bounds?の近くに重複して表示されます。境界にはオブジェクトとインタフェースが含まれているため、私の状況は少し異なりますが、もう一方の質問には2つのインタフェースがありますが、それでも適用できます。

私はアプリケーション全体を再設計して再構築する必要があるようです。一口。

管理者は、これを複製として閉じることができます...

+0

[どのように私は、複数の境界を持つ一般的なJava用キャストする必要がありますか?]の可能な重複は(http://stackoverflow.com/questions/318208/how-should-i-cast-for-java-generic-with -nultiple-bounds) –

答えて

0

私はこれのうちの方法は、正確にエレガントされていないが、doSomethingのためのいくつかのオーバーロードを持つことであると思う:

void doSomething(FunctionCallStatement node) ... 
void doSomething(FunctionCallExpression node) ... 
0

あなたはどのように引数としての参照を渡すことについて、フラグ機能へのインタフェースを使用しています関数呼び出し抽象化へのアクセスを提供するFunctionCallInterface

doSomethingは、関連情報にアクセスして実装オブジェクトの関連メソッドを呼び出すことができる限り、実際の実装タイプを知る必要はありません。

public class FunctionCallStatement extends Statement implements FunctionCallInterface { 
} 

void doSomething(FunctionCallInterface node) { 
} 
+0

'doSomething()'は、FunctionCallInterface機能と同様にNode機能にもアクセスする必要があります。そのため、汎用タイプの理由です。私はNodeと* FunctionCallInterfaceを渡すことができると思いますが、どちらも同じオブジェクトであることになります。 –

+0

@David Givenは、Nodeが実装している 'NodeInterface'を定義し、' FunctionCallInterface'それを拡張して、必要なすべての機能を提供します。 – rsp

関連する問題