【问题标题】:Force subclass to override method with itself as parameter强制子类以自身为参数覆盖方法
【发布时间】:2019-04-08 11:22:03
【问题描述】:

我有一个抽象事件类,它有一个抽象方法:

abstract boolean intersect(Event object);

此方法应根据特定子类的实例变量检查 Event 子类的两个实例是否相交。我想强制 Event 的任何子类覆盖其实例变量上的方法。设计这个的最佳方法是什么?这是我当前的实现,这是错误的,因为我正在更改参数类型。我也尝试过使用接口,但在类型参数方面遇到了类似的问题。

@Override
public boolean intersect(SubClassEvent e2) {

    boolean intersects = false;
    if(this.weekDay == e2.weekDay) {
        if (this.getStartTime() < e2.getStartTime() && this.getEndTime() > e2.getStartTime()) {
            intersects = true;
        }
        else if(this.getStartTime() >= e2.getStartTime() && this.getStartTime() < e2.getEndTime()){
            intersects = true;
        }
    }
    return intersects;
}

【问题讨论】:

    标签: java generics inheritance casting type-parameter


    【解决方案1】:

    如果将抽象类设为泛型,则可以允许子类将自己指定为参数类型:

    abstract class Event<T extends Event<T>> {
        abstract boolean intersect(T object);
    }
    

    子类将能够将自己的类型声明为参数。除非您的代码库使用原始类型,否则这应该可以工作。

    class SubClassEvent extends Event<SubClassEvent> {
         @Override
        boolean intersect(SubClassEvent object){return true;}
    }
    

    这个限制(或者说是例外)将是原始类型和其他类型事件的事件,这可以允许其他参数类型。

    【讨论】:

    • 谢谢!看来我对类型参数的理解存在一些差距,您的代码帮助清除了这些差距
    • 这并不能保证子类的intersect 方法会有自己的类型作为参数。以下编译:class AnotherSubClassEvent extends Event&lt;SubClassEvent&gt; { boolean intersect(SubClassEvent object) { return true; } }
    • @newacct 当然不能保证。但是,使用 Java 中的重写方法,我相信这是最接近允许子类使用不同但有界的参数类型的方法。没有这个,我相信答案是“不可能”。但我也应该指出这个限制 - 将编辑。谢谢
    【解决方案2】:

    这在 Java 中是不可能的。假设您有实现方法boolean intersect(SubClassEvent e2) 的子类SubClassEvent。然后,如果它还有一个子类SubSubClassEvent extends SubClassEvent,它将从SubClassEvent 继承方法boolean intersect(SubClassEvent e2),这取决于Java 中的继承方式。

    SubSubClassEvent 不必重写该方法,因为该方法在其超类SubSubClass 中是非抽象的。但是即使SubSubClassEvent 想要覆盖该方法,它也必须使用签名boolean intersect(SubClassEvent) 覆盖它。如果它实现了一个带有签名 boolean intersect(SubSubClassEvent) 的方法,则在 Java 方法覆盖规则下,它不会被视为对其超类中的方法 boolean intersect(SubClassEvent) 的覆盖。

    因此,SubSubClassEventEvent 的子类,其intersect 方法没有将自己的类型作为参数类型,违反了您的条件。

    【讨论】:

      猜你喜欢
      • 2011-05-21
      • 2017-11-18
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 2013-10-26
      相关资源
      最近更新 更多