2016-05-24 4 views
1

私はこのような類似の質問がたくさんあることを理解していますが、私がうまくいく解決策を見つけることができないため、私は説明しようとします..Java - オブジェクトがclassAまたはclassBのインスタンスである場合、

私はクラスTextFieldTextAreaを持つlibgdxゲームフレームワークを使用しています。 TextAreaTextFieldの拡張であり、いくつかの追加メソッドがあり、TextFieldメソッドのいくつかをオーバーライドしています。複数のテキスト行を持つ機能を追加します。

これらのクラスには追加の同じメソッドが含まれていますので、両方ともクラスTextFieldExtTextAreaExtで拡張しました。これらの両方で、doMethod1()doMethod2()というメソッドを追加しました。

だから、私はそれがTextFieldExtまたはTextAreaExtのいずれかに遭遇するとき、私はそれはいくつかのアクションを実行し、doMethod1()doMethod2()を実行したい、(TextFieldのスーパークラスおよび他の多くのオブジェクトである)Actorsを反復処理しています。

今私が望むのは、このようなものです。

if(actor instanceof TextFieldExt || actor instanceof TextAreaExt){ 
    (...) actor.doMethod1(); 
} 

私はこれが不可能である知っている、とJavaの目には、これらのメソッドが存在する保証がないため、鋳造またはステートメントのいずれかの種類がそれを許可しません。

私は両方のクラスで必要なメソッドを持つインターフェイスを構築しようとしましたが、それは正しい方法で実行されているように感じますが、それでも動作させることはできません。したがって、例えば私は持っています。

public interface ExtendedTextElement { 
    public void doMethod1(); 
    public void doMethod2(); 
} 

次に、私の拡張クラスでは、

public class TextFieldExt extends TextField implements ExtendedTextElement 
public class TextAreaExt extends TextArea implements ExtendedTextElement 

私の条件文で私は試してみます。インスタンスがTextFieldまたはTextAreaの拡張であるという保証がないため、当然、動作しませんので、私は基本メソッドにアクセスすることはできません

if(actor instanceof ExtendedTextElement){ ... 

だから私は立ち往生しています。別々の条件文とコードの重複を手作業で少しずつ手を加えることができますが、それはかなりのコードであり、むしろ適切な解決策があります。

+2

「TextField」と「TextArea」のどちらの基本メソッドが必要ですか?そして、どんな目的のために?これらのメソッドのシグネチャを 'ExtendedTextElement'インタフェースに追加するだけです。いくつかの合理的な解決法があるかもしれないが、あなたがしようとしていることの[小さな自己完結型の例](http://stackoverflow.com/help/mcve)を提供できれば助けになるだろうあなたの特定の要件。 – dimo414

+0

actorがTextFieldExtのインスタンスである場合、TextFieldExtにキャストしてメソッドを呼び出します。そのTextAreaExtのインスタンスがTextAreaExtにキャストされ、そのメソッドが呼び出されます。 –

+0

まったく信じられない@ dimo414、そのような単純な解決策とそれは動作します。私はそれについても考えなかったとは信じられません。ありがとうございました! – hamham

答えて

1

このすべてのユースケースでは動作しませんが、あなたがする必要があるすべてはTextFieldTextAreaの両方で定義されてをたまたまメソッドを呼び出している場合、あなたは例えば、あなたのインターフェイスにそのメソッドを追加することができます。

public interface ExtendedTextElement { 
    public void doMethod1(); 
    public void doMethod2(); 
    public void setText(String t); 
} 

あなたが必要とされ、これらのクラスのメソッド(s)は言いませんが、それらの両方がTextComponentを拡張するので、あなたもTextComponentに、あなたのオブジェクトをキャストしてみてください。これは、共有親クラスで定義されているメソッド(setText()など)に対して機能します。

これは、TextField/TextAreaのケースでは機能しませんが、インターフェイスを共有するクラス(親クラスではなく)を扱う場合、インターフェイスを定義してそのインスタンスをすべて強制することができますは、共有インタフェースのインスタンスでもあり、instanceofチェックは必要ありません。

public interface ImaginaryTextComponentInterface { 
    public void setText(String t); 
} 

public interface ExtendedTextElement extends ImaginaryTextComponentInterface { 
    public void doMethod1(); 
    public void doMethod2(); 
} 
+0

それはまだ少しマニュアルとハッキリを感じていますが、私がまだ実装している最高のソリューションです。私はあなたが本当にあまりにも多くの変更をしたくないライブラリや外部クラスを操作している場合は、このような回避策が本当に適用されると思います。そうでなければ、必要なメソッドはすぐにスーパー( 'TextField')に入り、これのどれかが必要です。 – hamham

+0

間違いなくハッキーですが、うまくいくでしょう。あなたの実際のユースケースを分かち合うことができれば、根本的な問題に対してより良い解決策を提供できるかもしれません。 – dimo414

+0

私が追加した非常に多くの機能があります。そのうちの1つは選択ハンドルです。これらは、 'TextField' /' TextArea'の境界を超えて拡張され、他の要素の上にとどまる必要があるため、最後に追加された 'Stage'の外部アクターです。これを行うために、拡張クラスに追加したいくつかの追加機能は、選択領域を取得して設定するヘルパーです。理想的には、これらは 'TextField'クラスに入りますが、基本的な変更を絶対最小値に保ちたいので、将来私の改造をlibgdxの更新に適用するのは簡単です。 – hamham

関連する問題