在一个类中覆盖多个类的许多方法

3
public class EventController extends MouseAdapter implements ActionListener {

    private EventModel model;
    private EventView  view;
    String tableClick;
    Events events;    

    /** Constructor */
   public EventController(EventModel myModel, EventView myView){
       model = myModel;
       view = myView;     
   }

   public void setUpListeners() {
       this.view.addEventButton.addActionListener(this); 
       this.view.addEventMenuItem.addActionListener(this);
       this.view.editEventMenuItem.addActionListener(this);
       this.view.tableEvent.addMouseListener(this);                
   }

   @Override
   public void actionPerformed(ActionEvent e){
       Object button = e.getSource();
       if(button==this.view.addEventButton) {
           setEventDetails();          
       }                
   }

   @Override
   public void mouseClicked(java.awt.event.MouseEvent event) {
      int rowSelected = view.tableEvent.getSelectedRow();
       //blahblahblah
      view.changeDisplay(events);
    }

我该如何重写KeyListener类的keyPressed方法,就像我已经对mouseClicked和ActionPerformed做过的那样,而不想重写keyTyped和keyReleased,只是单独重写keyPressed。交互发生在另一个名为VIEW的类中。


你能展示一下代码的其余部分吗?这样我们就可以更好地理解问题了。我看不出有什么阻止你只使用@Override public void keyPressed(...)的东西。 - ameed
6个回答

9

你不能这样做,因为Java只支持单继承。所以你需要实现KeyListener,并提供这两个方法的实现(什么也不做)。

更好的设计是将责任分离,为鼠标事件、动作事件和键盘事件各创建一个类。这些类可以作为匿名内部类实现。


7

Java不支持多重继承,因此您无法扩展多个类,您不能像这样实现:

class EventController extends MouseAdapter, KeyAdapter

您可以实现多个接口,但似乎您想避免这样做。

现在,解决这种问题的方法总是相同的,使用组合而非继承。您可以轻松地拥有两个内部类:一个扩展了 KeyAdapter,另一个扩展了 MouseAdapter。然后,在稍后需要添加监听器时,您使用类的字段而不是 this

像这样:

import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;

public class EventController {
    private EventModel model;
    private EventView  view;
    String tableClick;
    Events events;

    private MouseAdapter mouseListener = new MouseAdapter() {

        @Override
        public void mouseClicked(java.awt.event.MouseEvent event) {
          int rowSelected = view.tableEvent.getSelectedRow();
           //blahblahblah
          view.changeDisplay(events);
        }
    };

    private KeyAdapter keyAdapter = new KeyAdapter() {
        public void keyTyped(java.awt.event.KeyEvent e) {
            // Perform here whatever is needed
            // You also have access to your enclosing instance EventController.this and its methods
        }
    };

    private ActionListener actionListener = new ActionListener() {@Override
               public void actionPerformed(ActionEvent e){
           Object button = e.getSource();
           if(button==this.view.addEventButton) {
               setEventDetails();          
           }

       }



    /** Constructor */
   public EventController(EventModel myModel, EventView myView){
       model = myModel;
       view = myView;     
    }

   public void setUpListeners() {
       this.view.addEventButton.addActionListener(actionListener); 
       this.view.addEventMenuItem.addActionListener(actionListener);
       this.view.editEventMenuItem.addActionListener(actionListener);
       this.view.tableEvent.addMouseListener(mouseListener);
       // Here you can also add the keyadapter to your views
   }


 }

非常感谢,解决方案描述得非常清楚,正是我所需要的。 - MooHa

3

Swing提供了适配器类,以帮助覆盖方法而无需在Listener类中完成所有方法。

如果您只需要实现KeyListener的某些方法,则应使用KeyAdapter类。


他已经扩展了MouseAdapter,因此不能再扩展KeyAdapter。 - JB Nizet
@JBNizet - OP 可以使用匿名内部类或私有嵌套类来解决多重继承问题。 - Jesse Webb

3

您不能这样做。

一个类只能从另一个类继承(Java中不允许多重继承)。

一个类可以实现多个接口,但是由于接口提供方法的实现,您必须提供它(或声明类为abstract,甚至是一个interface本身 )。

由于您已经扩展了MouseAdapter,因此您必须实现ActionListener me


3

不要直接在EventController中提供监听器,而是在内部类中实现。例如,一个内部类可以继承MouseAdapter,并调用EventController方法来执行实际工作。另一个内部类可以继承KeyAdapter,并调用其他EventController方法。

将内部类的实例作为监听器附加,而不是直接附加EventController本身。


0

搜索组合模式和外观模式,以重用代码。

class SilverBullet implements Interface1, Interface2 {
   Concrete1 c1;
   Concrete2 c2;

   void someMethod() {
       c1.someMethod();
   } 

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接