强制子类以自身作为参数覆盖方法

时间:2018-11-05 05:07:50

标签: java generics inheritance casting type-parameter

我有一个抽象的Event类,它具有抽象的方法:

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

2 个答案:

答案 0 :(得分:12)

如果使抽象类通用,则可以允许子类将自身指定为参数类型:

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

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

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

对此的限制(或更确切地说是对此的例外)将是原始类型和其他事件类型的事件,这可能允许其他参数类型。

答案 1 :(得分:0)

这在Java中是不可能的。考虑您具有实现方法SubClassEvent的子类boolean intersect(SubClassEvent e2)。然后,如果它还有一个子类SubSubClassEvent extends SubClassEvent,它将基于Java中继承的工作原理,从boolean intersect(SubClassEvent e2)继承方法SubClassEvent

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

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