如何确保接口实现扩展特定类?

时间:2012-07-23 03:08:09

标签: java swing interface awt multiple-inheritance

我有两种类型的编辑器。一个是JTextArea的子类,一个是JTable的子类(JTextAreaJTable都是JComponent的子类。我希望我的两个课程TextAreaEditorTableEditor实现接口Editor,其中只有public String getText()方法。

我希望客户端代码只使用Editor接口。问题是,Editor的所有JComponent使用方法都与setEnabled(bool)类似。由于我的编辑器是一个接口,我无法扩展JComponent,因此在调用这些方法时我必须使用实现而不是接口。所以我认为不是使用接口,而是简单地使Editor成为JComponent的子类,并使我的类扩展它。问题是像TextAreaEditor这样的类已经扩展了像JTextArea这样的类,所以我不能让它们扩展另一个类。

有没有办法确保我的Editor类是一个JComponent,我的具体编辑器类是EditorJComponent的子类?

6 个答案:

答案 0 :(得分:4)

如果在编辑器界面的子类中公开您关心的JComponent方法,那么它们将由您的类“追溯”实现。

以下是一些展示这个想法的代码:

interface Editor { 
  String getText(); 
}

interface SwingEditor extends Editor { 
  void setEnabled(bool); // has to match *exactly* the signature from JComponent
}

class TableEditor extends JTable implements SwingEditor {
   // implement your getText(), and anything else you need 
   // no need to implement setEnabled, as it is provided by JTable
}

SwingEditor te = new TableEditor();
te.setEnabled(true); // will call JComponent's method

我假设你真的需要继承这里,通常组合是Swing UI代码的更好选择。

答案 1 :(得分:3)

使用composition over inheritacne。大部分时间继承都不是正确的解决方案,在您的情况下,它将使您免于编写相当多的代码。

TextAreaEditorTableEditor都拥有他们需要的JComponent个实例。 将所需的所有方法添加到界面,然后将这些调用委托给JComponet

例如:

public class TextAreaEditor implements Editor {
     private final JTextArea textArea = new JTextArea();

     public void setEnabled(bool isEnabled) {
          return textArea.setEnabled(isEnabled);
     }

     //... your own methods plus other methods from JComponent
}

您可能希望获得更多花哨并使用某种依赖注入来实例化JComponent,但这不是必需的。但是,如果所有更改都需要注入特定的JComponent,它可以解决必须上课的问题。

如果您需要更多澄清,请告诉我。

答案 2 :(得分:2)

如果您确实需要将Editor课程设为JComponent,则可以选择简单地记录此课程并在代码中执行演员。不是最简洁的解决方案,但到目前为止最简单。

另一种方法是向Editor接口添加额外的方法:

public JComponent getComponent();

您的Editor个实例只需返回this即可实现此方法。

后一种方法的好处是您可以使用所有JComponent方法,而不必在界面中复制它们,并在2个月内得出结论,您忘记添加其中一个{接口的{1}}方法

答案 3 :(得分:1)

以下设计负责:

public class TextAreaEditor extends JTextArea implements Editor {
//provide your implementation of getText()
//setEnabled(bool) doesn't have be implemented as JComponent will provide
}

TextAreaEditor te = new TextAreaEditor();
te.setEnabled(true); // will call JComponent's impl

根据上面的代码,你自己的编辑器(TextAreaEditor)的具体实现是JComponent的编辑器和子类。

答案 4 :(得分:0)

我可能会创建一个新的表和textarea类来扩展它们各自的超类,并实现像这样的编辑器界面

public class JTextAreaEditor extends JTextArea implements Editor {
...
}

然后使用composition来公开Editor接口的方法

    public class JTextAreaEditor extends JTextArea implements Editor {
       private Editor editor;

       public String getValue() {
          return editor.getValue();
       }
       ...
    }

答案 5 :(得分:0)

我认为你的论点是不正确的:对于一个接口(编辑器),你不应该关心如何实现这些实现。你说你所有的编辑器实现都需要是JComponent。这就是现在发生的事情,但它永远不需要成为“编辑”的“要求”。编辑器的设计没有理由强加于此,只要实现符合编辑器要求的内容(getText())。

您所谈论的内容主要是“普通”编辑器实现的默认基类。再一次,请注意,只要它们符合您的编辑器界面,是否可以选择使用此基类实现。

public interface Editor {
    String getText();
}

public abstract class JComponentEditor extends JComponent 
        implements Editor {
    //.....
}

public TextAreaEditor extends JComponentEditor {
    public String getText() {
        // implements TextAreaEditor's version of getText
    }
}

编辑:我认为我对OP的问题有点误解。无论如何,我的答案中的主要论点仍然存在:强制执行“......我的编辑器类是JComponent,而我的具体编辑器类是JComponent的编辑器和子类”是没有意义的。它只是编辑器的实现细节