Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重写类';方法,通过在子类上迭代_Java_Inheritance_Methods_Subclass_Superclass - Fatal编程技术网

Java 重写类';方法,通过在子类上迭代

Java 重写类';方法,通过在子类上迭代,java,inheritance,methods,subclass,superclass,Java,Inheritance,Methods,Subclass,Superclass,这是一个需要解释的复杂问题,所以我做了一个糟糕的MSPaint 假设我有一个子类对象列表。其中一些包含一个名为onEvent()的方法。在我的onEvent()中来自一个完全不相关的类,我想遍历我的对象列表并调用它们的onEvent()s(如果存在)。显然,如果我尝试遍历类型超类的列表,它必须是一个抽象方法才能工作。我只希望某些子类有这个onEvent()方法 我可能会让你很难理解,但我希望你能理解,任何想法都会被感激。我认为你应该重新考虑你的课堂设计 你的问题有两种解决办法 将onEvent

这是一个需要解释的复杂问题,所以我做了一个糟糕的MSPaint

假设我有一个子类对象列表。其中一些包含一个名为
onEvent()的方法。在我的
onEvent()中
来自一个完全不相关的类,我想遍历我的对象列表并调用它们的
onEvent()s(如果存在)。显然,如果我尝试遍历类型超类的列表,它必须是一个抽象方法才能工作。我只希望某些子类有这个onEvent()方法


我可能会让你很难理解,但我希望你能理解,任何想法都会被感激。

我认为你应该重新考虑你的课堂设计

你的问题有两种解决办法

  • onEvent
    方法作为具有空主体的非抽象方法拉到您的超类中。然后,您只能在适当的地方重写子类中的内容

  • 引入一个接口,我们称之为
    EventHandler
    ,它声明了方法
    onEvent
    。在适当的地方在子类中实现这个接口。然后将列表更改为
    EventHandler
    对象的列表,或者将其保持原样,并使用
    instanceof
    检查对象是否是迭代中的
    EventHandler

  • 在超类中:

    // subclasses should override this if they want onEvent to be supported
    public boolean isOnEventSupported() {
        return false;
    }
    
    public final void onEvent() {
        if (!isOnEventSupported()) {
            throw new UnsupportedOperationException("onEvent is not supported");
        }
        doOnEvent();
    }
    
    protected void doOnEvent() {
        // do nothing : subclasses should override this if they want onEvent to do something useful
    }
    
    很简单:

    interface Listener {
       void onEvent();
    }
    
    public class SuperClass {}
    
    public class SubClass1 extends SuperClass implements Listener {
        public void onEvent();
    }
    
    public class SubClass2 extends SuperClass {}
    
    public class DifferentClass implements Listener {
        private final List<SuperClass> objects;
    
        public void onEvent() {
            for (SuperClass o : objects) {
                if (o instanceof Listener) {
                   ((Listener)o).onEvent();
                }
            }
        }
    }
    
    接口侦听器{
    void onEvent();
    }
    公共类超类{}
    公共类子类1扩展了实现侦听器的超类{
    public void onEvent();
    }
    公共类子类2扩展了超类{}
    公共类DifferentClass实现侦听器{
    私有最终列表对象;
    public void onEvent(){
    for(超类o:对象){
    if(侦听器的o实例){
    ((侦听器)o.onEvent();
    }
    }
    }
    }
    

    但对我来说,你的设计有点凌乱。我不知道您的具体情况,但使用
    instanceof
    通常会让人觉得设计很糟糕

    最简单的解决方案是将
    onEvent
    抽象为超类。然后在不支持它的子类上用空体覆盖它。

    所有子类都将使用OneEvent()方法,您无法阻止继承。如果onEvent()不是私有/静态的。显然,如果我尝试遍历类型超类的列表,它必须是一个抽象方法才能工作。没有这一行吗?还有可能的答案:)我认为在大多数情况下,如果该方法不受支持,则抛出异常是不利的(例如,当您只需遍历列表并调用OneEvent时)。因此,在大多数情况下,一个简单的空方法体应该是合适的,并且不那么复杂。如果OneEvent返回void,那么默认情况下您实际上可以什么都不做。如果它应该返回非空的内容,那么它可能不可能。在本例中,使用isOnEventSupported()方法可以在实际调用该方法之前检查是否可以调用该方法。