在GUI开发期间替代Java中的多继承

时间:2012-11-09 10:22:37

标签: java gwt

我遇到了以下困境:Java中没有多重继承,但我需要它,如何避免它?

以下是我开始考虑它的原因。

我需要一个具有多个特定属性和行为的文本框(处理焦点和模糊事件)。我毫不犹豫地开发了DecorativeTextBox:

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提出的变体,但在每种情况下我都遇到了一个问题,我有一个方法(它的签名无法更改)添加小部件,其中一个args是Widget本身。因此,如果我不是从Widget的子类中继承子类,那么我会破坏很多类。

仍然继续考虑解决方案。

3 个答案:

答案 0 :(得分: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。

答案 1 :(得分:3)

您应该使用Interfaces来定义事物的交互方式,并使用基类来强制执行行为。这样,您可以使用composition +接口显式获得多继承的好处。

在您的情况下:提取TextBox类的公共接口,并将其用于DecorativeTextBox类。

答案 2 :(得分:1)

如果一切都失败了,你可以这样做:

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

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

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

我假设你想要通过继承来解决这个问题。否则,您可以使用组合。在大多数情况下,它将是一个更好的选择。