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 库)。但我不明白如何在这里编织构图。

更新

纠正我如果我以错误的方式理解安德斯约翰森所说的话。

解决方案应如下所示:

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
    }
}

更新

我尝试了 Anders Johansen 和 Hilbrand Bouwkamp 建议的变体,但在每种情况下,我都遇到了一个问题,即我有一个添加小部件的方法(其签名无法更改),其中一个参数是 Widget 本身。因此,如果我不是从 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 回答