2

私は次のジレンマに直面しました。Javaには多重継承はありませんが、それが必要です。どうすれば回避できますか?

それが私が考え始めた理由です。

いくつかの特定のプロパティと動作(フォーカスとブラーイベントが処理される)を備えたテキストボックスが必要でした。私はためらうことなくDecoratedTextBoxを開発しました:

public class DecoratedTextBox extends TextBox implements FocusHandler, BlurHandler {
    public void onBlur(BlurEvent event) {
        //cool feature implementation
    }

    public void onFocus(FocusEvent event) {
        //another cool feature
    }

    //other cool features
}

GUIは見栄えが良くなりましたが、PasswordTextBoxを考慮していませんでした。また、DecoratedTextBoxと同じプロパティと動作が必要です。ただし、PasswordTextBoxはTextBoxから継承されており、実際には別のクラス階層ブランチです。TextAreaにもこれらのクールなプロパティや動作などがすべて備わっていれば素晴らしいと思いました。

では、多重継承についての考えにつながるという私の設計の何が問題になっていますか?上記の要件を満たすために何をしなければなりませんか?

いくつかの説明

その結果、PasswordTextBox、TextAreaなどの機能を利用するためにそれらを継承する必要がありました(これらのクラスはGWTライブラリからのものです)。でも、ここで構図の織り方がわかりません。

アップデート

AndersJohansenが間違った方法で言ったことを理解した場合は訂正してください。

解決策は次のようになります。

public class DecoratedTextBox extend AbstractEventHandler {
    private TextBox textBox;

    //wrap TextBox methods
    public String getText() {
        return textBox.getText();
    }
}

public class DecoratedPasswordTextBox  extend AbstractEventHandler {
    private PasswordTextBox passwordTextBox;

    //wrap TextBox methods
    //...
}

public class DecoratedTextArea  extend AbstractEventHandler {
    private TextAre textArea;

    //wrap TextBox methods
    //...
}

public abstract class AbstractEventHandler implements FocusHandler, BlurHandler {
    public void onBlur(BlurEvent event) {
        //default cool feature implementation
    }

    public void onFocus(FocusEvent event) {
        //another default cool feature implementation
    }
}

更新しました

AndersJohansenとHilbrandBouwkampによって提案されたバリアントを試しましたが、いずれの場合も、ウィジェットを追加するメソッド(署名は変更できません)があり、引数の1つがウィジェット自体であるという問題が発生しました。したがって、Widgetのサブクラスであるものからサブクラス化していない場合は、多くのクラスを分割します。

まだ解決策を考え続けてください。

4

3 に答える 3

5

どのようなクールな機能を追加したいかはわかりませんが、次のようなTextBoxBaseDecoratorクラスを作成するのはどうでしょうか。

public class TextBoxBaseDecorater implements FocusHandler, BlurHandler, HasAttachHandlers {
  private final TextBoxBase textBoxBase;
  private final ArrayList<HandlerRegistration> handlers = new ArrayList<HandlerRegistration>();

  /*
   * Pass the TextBoxBase extending widget to be decorated.
   */
  public TextBoxBaseDecorater(TextBoxBase textBoxBase) {
    this.textBoxBase = textBoxBase;
    textBoxBase.addAttachHandler(this);
  }

  public void onBlur(BlurEvent event) {
    //cool feature implementation
  }

  public void onFocus(FocusEvent event) {
    //another cool feature
  }

  public void onAttachOrDetach(AttachEvent event) {
     if (event.isAttached() {
       handlers.add(textBoxBase.addBlurHandler(this));
       handlers.add(textBoxBase.addFocusHandler(this));
     } else {
       for (HandlerRegistration rh: handlers) {
          rh.removeHandler();
       }
       handlers.clear();
     }
  }

  //other cool features

}

TextBox、PasswordTextBox、TextAreaなど、特定のウィジェットのラッパーを作成するサブクラスを作成できます。

于 2012-11-09T11:10:29.690 に答える
3

物事がどのように相互作用するかを定義するためのインターフェースと、動作を強制するための基本クラスを使用する必要があります。このようにして、合成+インターフェースを使用して、多重継承の利点を明示的に得ることができます。

状況:TextBoxクラスの共通インターフェースを抽出し、それをDecoratedTextBoxクラスに使用します。

于 2012-11-09T10:26:08.053 に答える
1

他のすべてが失敗した場合は、これを行うことができます:

public class ClassA extends TextBox implements FocusHandler {
 // ...
}

public class ClassB extends ClassA implements BlurHandler {
 // ...
}

public class DecoratedTextBox extends extends ClassB  {
    //other cool features
}

この問題を継承で解決したいと思います。それ以外の場合は、compositionを使用できます。ほとんどの場合、それはより良い代替手段になります。

于 2012-11-09T10:25:57.640 に答える