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

Java 如何确保接口实现扩展特定类?,java,swing,interface,awt,multiple-inheritance,Java,Swing,Interface,Awt,Multiple Inheritance,我有两种类型的编辑。一个是JTextArea的子类,一个是JTable的子类(JTextArea和JTable都是JComponent的子类)。我想要我的两个类,TextAreaEditor和TableEditor来实现接口Editor,它只有方法publicstringgettext() 我希望客户端代码只使用编辑器界面。问题是,我所有的编辑器都使用JComponent的方法,比如setEnabled(bool)。因为我的编辑器是一个接口,我不能让它扩展JComponent,所以在调用这些方法

我有两种类型的编辑。一个是
JTextArea
的子类,一个是
JTable
的子类(
JTextArea
JTable
都是
JComponent
的子类)。我想要我的两个类,
TextAreaEditor
TableEditor
来实现接口
Editor
,它只有方法
publicstringgettext()

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

有没有办法确保我的
Editor
类是一个JComponent,而我的具体编辑器类是
Editor
s和
JComponent
的子类。大多数情况下,继承确实不是正确的解决方案,在您的情况下,它将使您免于编写大量代码

让您的
TextAreaEditor
TableEditor
都具有所需的
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
,那么它可以解决必须插入类的问题


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

我可能会创建一个新的table和textarea类,扩展它们各自的超类,并实现这样的编辑器接口

public class JTextAreaEditor extends JTextArea implements Editor {
...
}
然后使用composition公开编辑器界面的方法

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

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

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

我认为您的论点完全不正确:对于接口(编辑器),您不应该关心实现是如何实现的。您说过所有编辑器实现都需要是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的编辑器和子类”是没有意义的。这只是编辑器的实现细节,下面的设计会考虑到这一点:

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的子类。

如果您真的需要您的
编辑器
类成为
JComponent
,您也可以选择简单地记录它并在代码中执行强制转换。这不是最简洁的解决方案,但迄今为止是最简单的

另一种方法是向
编辑器
界面添加一个额外的方法:

public JComponent getComponent();
您的
编辑器
实例可以通过简单地返回
this
来实现此方法


后一种方法的好处是,您可以使用所有
JComponent
方法,并且不必在界面中复制它们,并且在2个月后得出结论,您忘记将其中一个
JComponent

方法添加到界面中

这有点不清楚。您可以发布一些示例类/实现吗?特别是,不清楚为什么编辑器必须是一个类?对我来说,听起来你们可以使用抽象类。使编辑器成为扩展JComponent的抽象类,然后使TextAreaEditor和TableEditor扩展JComponent并实现setEnabled(bool)。我试着用一个新标题来解释你的问题。这就是你真正想问的吗?@Arkadiy最初是一个界面。我需要调用
editor.setEnabled(true)
时遇到问题,因为
setEnabled()
是JComponent类的一个方法@星号问题是TextAreaEditor需要扩展JTextArea,所以它不能扩展抽象类@埃里克森:是的,这对我来说是个更好的头衔。这很难表达。您是否可以将setEnabled添加到编辑器界面?
    public class JTextAreaEditor extends JTextArea implements Editor {
       private Editor editor;

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