【问题标题】:How can I ensure that an interface implementation extends a particular class?如何确保接口实现扩展特定类?
【发布时间】:2012-07-23 03:08:09
【问题描述】:

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

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

有什么方法可以确保我的 Editor 类是 JComponent,并且我的具体编辑器类是 Editors 和 JComponent 的子类?

【问题讨论】:

  • 这有点不清楚。你能发布一些示例类/实现吗?特别是,不清楚为什么 Editor 必须是一个类?
  • 对我来说听起来你可以使用抽象类。制作扩展JComponent的Editor抽象类,然后使TextAreaEditor和TableEditor扩展JComponent并实现setEnabled(bool)。
  • 我尝试在一个新标题中记录我对您问题的解释。这真的是你要问的吗?
  • @Arkadiy 最初它是一个界面。当我需要调用editor.setEnabled(true) 时遇到问题,因为setEnabled() 是JComponent 类的一个方法。 @Asterisk问题在于TextAreaEditor需要扩展JTextArea,因此它也不能扩展抽象类。 @erickson 是的,这对我来说似乎是一个更好的标题。很难说。
  • 可以在编辑器界面添加 setEnabled 吗?

标签: java swing interface awt multiple-inheritance


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    使用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,那么它可以解决必须上课的问题。

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

    【讨论】:

      【解决方案3】:

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

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

      public JComponent getComponent();
      

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

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

      【讨论】:

        【解决方案4】:

        下面的设计可以解决这个问题:

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

        【讨论】:

          【解决方案5】:

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

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

          然后使用组合来暴露Editor接口的方法

              public class JTextAreaEditor extends JTextArea implements Editor {
                 private Editor editor;
          
                 public String getValue() {
                    return editor.getValue();
                 }
                 ...
              }
          

          【讨论】:

            【解决方案6】:

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

            您所说的主要是“普通”编辑器实现的默认基类。再次注意,实现是否选择使用此基类是他们的选择,只要它们符合您的 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的实现细节

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-02-16
              • 1970-01-01
              • 2010-09-12
              • 2013-07-17
              • 2019-04-07
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多