【问题标题】:Override a class' method by iterating over a subclass通过迭代子类来覆盖类的方法
【发布时间】:2014-01-30 11:03:12
【问题描述】:

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

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

我可能很难理解,但我希望你能明白,任何想法都将不胜感激。

【问题讨论】:

  • 所有子类都有 onEvent() 方法,你不能阻止继承。如果 onEvent() 不是私有/静态的。 显然,如果我尝试遍历超类类型的列表,它必须是一个抽象方法才能工作没有得到这一行?

标签: java inheritance methods subclass superclass


【解决方案1】:

我认为你应该重新考虑你的班级设计。

您的问题有两种解决方案

  1. onEvent 方法作为具有空主体的非抽象方法拉到您的超类中。然后你可以只在适当的地方覆盖子类。

  2. 引入一个接口——我们称之为EventHandler——声明方法onEvent。在适当的情况下在您的子类中实现此接口。然后将您的列表更改为 EventHandler 对象的列表,或者保持原样并使用 instanceof 在您的迭代中检查对象是否为 EventHandler

【讨论】:

    【解决方案2】:

    在超类中:

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

    【讨论】:

    • 也可能的答案:)
    • 我认为在大多数情况下,如果不支持该方法(例如,当您想简单地遍历列表并调用 onEvent 时)抛出异常是不利的。所以在大多数情况下,一个简单的空方法体应该是合适的并且不太复杂。
    • 如果 onEvent 返回 void,那么您实际上可以默认什么都不做。如果它应该返回不为空的东西,那么它可能是不可能的。在这种情况下,使用 isOnEventSupported() 方法可以在实际调用该方法之前检查您是否可以调用它。
    【解决方案3】:

    很简单:

    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();
                }
            }
        }
    }
    

    但对我来说,你的设计有点乱。我不知道你的具体情况,但instanceof 的使用通常是糟糕的设计!

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-17
        • 1970-01-01
        • 1970-01-01
        • 2019-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多