简体   繁体   English

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

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

I have two types of editors. 我有两种类型的编辑器。 One is a subclass of JTextArea and one is a subclass of JTable ( JTextArea and JTable are both subclasses of JComponent ). 一个是JTextArea的子类,一个是JTable的子类( JTextAreaJTable都是JComponent子类)。 I want my two classes, TextAreaEditor and TableEditor to implement the interface Editor , which just has the method public String getText() . 我想要我的两个类TextAreaEditorTableEditor来实现接口Editor ,它只有public String getText()

I want the client code to simply use the Editor interface. 我希望客户端代码只使用Editor界面。 The issue is, all of my Editor s use methods of JComponent , like setEnabled(bool) . 问题是,我的所有Editor使用JComponent方法,比如setEnabled(bool) Since my editor is an interface and I can't make it extend JComponent, I have to use the implementations instead of the interface when calling these methods. 由于我的编辑器是一个接口,我无法扩展JComponent,因此在调用这些方法时我必须使用实现而不是接口。 So I thought that instead of using an interface, I can simply make Editor a subclass of JComponent and make my classes extend that. 所以我认为不是使用接口,而是简单地将Editor作为JComponent的子类,并让我的类扩展它。 The issue is classes like TextAreaEditor already extend some class like JTextArea , so I can't make them extend another class. 问题是像TextAreaEditor这样的类已经像JTextArea那样扩展了一些类,所以我不能让它们扩展另一个类。

Is there any way to make sure that my Editor class is a JComponent, and that my concrete editor classes are Editor s and subclasses of JComponent ? 有没有办法确保我的Editor类是一个JComponent,我的具体编辑器类是JComponent Editor和子类?

If you expose the JComponent methods you care about in a subclass of your editor interface, they would be 'retroactively' implemented by your class. 如果在编辑器界面的子类中公开您关心的JComponent方法,那么它们将由您的类“追溯”实现。

Here is some code to demonstrate the idea: 以下是一些用于演示该想法的代码:

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

I assume you really need inheritance here, in general often composition is a better option for Swing UI code. 我假设你真的需要继承这里,通常组合是Swing UI代码的更好选择。

Use composition over inheritacne . 使用组合而不是遗传 Most of the time inheritance is really not the right solution, and in your case, it'll save you from writing quite a bit of code. 大部分时间继承都不是正确的解决方案,在您的情况下,它将使您免于编写相当多的代码。

Have your TextAreaEditor and TableEditor both have an instance of the JComponent they need. TextAreaEditorTableEditor都有他们需要的JComponent实例。 Add all the methods you need to your interface, and then delegate those calls to the JComponet . 将所需的所有方法添加到接口,然后将这些调用委托给JComponet

For example: 例如:

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
}

You might want to get a bit more fancy and use some sort of dependency injection to instantiate the JComponent , but that's not really necessary. 您可能希望获得更多花哨并使用某种依赖注入来实例化JComponent ,但这不是必需的。 It could, however, solve the problem of having to have to classes if all the changes is which particular JComponent you need to inject. 但是,如果所有更改都是您需要注入的特定JComponent ,它可以解决必须拥有类的问题。

Let me know if you need more clarificaiton. 如果您需要更多说明,请告诉我。

If you really need your Editor class to be a JComponent as well you can opt to simply document this and perform a cast in your code. 如果你真的需要你的Editor类成为JComponent ,你可以选择简单地记录它并在你的代码中执行强制转换。 Not the most neat solution, but by far the easiest. 不是最简洁的解决方案,但到目前为止最简单。

Another approach would be to add an extra method to the Editor interface: 另一种方法是在Editor界面中添加一个额外的方法:

public JComponent getComponent();

where your Editor instances could implement this method by simply returning this . 您的Editor实例可以通过简单地返回this来实现此方法。

The benefit of the latter approach is that you can use all JComponent methods, and do not have to duplicate them in your interface, and come to the conclusion in 2 months that you forgot to add one of the JComponent methods to your interface 后一种方法的好处是你可以使用所有JComponent方法,而不必在你的界面中复制它们,并在2个月内得出结论,你忘了将一个JComponent方法添加到你的界面

The following design takes care of it: 以下设计负责:

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

as per the above code your own concrete implementations of Editor (TextAreaEditor) is an Editor and subclass of JComponent. 根据上面的代码,您自己的编辑器(TextAreaEditor)的具体实现是JComponent的编辑器和子类。

I would probably create a new table and textarea class extending their respective super class, and implementing an editor interface like so 我可能会创建一个新表和textarea类来扩展它们各自的超类,并实现这样的编辑器界面

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

Then use composition to expose the methods of the Editor interface 然后使用composition来公开Editor接口的方法

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

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

I think your argument is simply incorrect: For an interface (Editor), you shouldn't concern on how the implementations are implemented. 我认为你的论点是不正确的:对于一个接口(编辑器),你不应该关心如何实现这些实现。 You said all your Editor implementation needs to be JComponent. 你说你所有的编辑器实现都需要是JComponent。 That's just what happens now but it is never need to be a "requirement" for being an "Editor". 这就是现在发生的事情,但它永远不需要成为“编辑”的“要求”。 The design of Editor have no reason to impose on that, as long as the implementation conforms to what Editor asks for (getText() ). 只要实现符合Editor要求的内容(getText()),Editor的设计就没有理由强加于此。

What you are talking on is mostly a default base class for "normal" Editor implementations. 你所谈论的主要是“普通”编辑器实现的默认基类。 Once again, note that whether the implementation choose to use this base class is their choice, as long as they conform to your Editor interface. 再次注意,只要它们符合您的编辑器界面,是否可以选择使用此基类的实现。

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

EDIT: I think I bit misunderstood a bit on the question of OP. 编辑:我想我对OP的问题有点误解了。 Anyway, the main argument in my answer still holds: It do not make sense to enforce "...that my Editor class is a JComponent, and that my concrete editor classes are Editors and subclasses of JComponent". 无论如何,我的答案中的主要论点仍然存在:强制执行“......我的编辑器类是JComponent,而我的具体编辑器类是JComponent的编辑器和子类”是没有意义的。 It is just the implementation detail of Editor 它只是Editor的实现细节

暂无
暂无

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

相关问题 我怎样才能保证实现接口的类也扩展了类? - How can I guarantee that a class that implements an interface also extends a class? 检查类或接口是否实现或扩展特定接口 - To check a class or an interface implements or extends a particular interface 如何添加对象 <? extends Interface> ? - How can I add an object to <? extends Interface>? 我如何确保通过接口实现公共静态功能 - How do i ensure implementation of a public static function with interface 如何使现有的Java类/接口实现单例? - How can I make an existing Java class/interface implementation a singleton? 如何确保类注释参数在编译时扩展接口? - How do you ensure a class annotation parameter extends an interface at compile time? 需要参数扩展特定类并实现特定接口 - Requiring an argument extends a particular class AND implements a particular interface 如何实现扩展接口的类,该接口接受自身的参数? - How can I implement a class which extends an interface which accepts arguments of itself? 如何区分kotlin的类继承(在java中扩展)和接口实现(实现)这里kotlin使用(:)两者? - How to Differentiate between kotlin's class inheritence(extends in java) and interface implementation(implements in ) here kotlin uses ( : ) for both? 如何在具有扩展另一个接口的接口的实现上设置限定符 - How to set Qualifier on an Implementation that has an interface which extends another interface
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM