繁体   English   中英

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

[英]How can I ensure that an interface implementation extends a particular class?

我有两种类型的编辑器。 一个是JTextArea的子类,一个是JTable的子类( JTextAreaJTable都是JComponent子类)。 我想要我的两个类TextAreaEditorTableEditor来实现接口Editor ,它只有public String getText()

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

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

如果在编辑器界面的子类中公开您关心的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代码的更好选择。

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

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 ,它可以解决必须拥有类的问题。

如果您需要更多说明,请告诉我。

如果你真的需要你的Editor类成为JComponent ,你可以选择简单地记录它并在你的代码中执行强制转换。 不是最简洁的解决方案,但到目前为止最简单。

另一种方法是在Editor界面中添加一个额外的方法:

public JComponent getComponent();

您的Editor实例可以通过简单地返回this来实现此方法。

后一种方法的好处是你可以使用所有JComponent方法,而不必在你的界面中复制它们,并在2个月内得出结论,你忘了将一个JComponent方法添加到你的界面

以下设计负责:

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的编辑器和子类。

我可能会创建一个新表和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();
       }
       ...
    }

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

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

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的编辑器和子类”是没有意义的。 它只是Editor的实现细节

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM