Force subclass to override method with itself as parameter
Asked Answered
R

2

13

I have an abstract Event class which has an abstract method:

abstract boolean intersect(Event object);

This method should check if two instances of an Event subclass intersect based on the instance variables of the particular subclass. I want to force any subclass of Event to override the method on its instance variables. What is the best way to design this? This is my current implementation, which is wrong since I am changing the parameter type. I have also tried using interfaces, but have run into similar problems with type parameters.

@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;
}
Roa answered 5/11, 2018 at 5:7 Comment(0)
P
12

If you make the abstract class generic, you can allow subclasses to specify themselves as parameter type:

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

Subclasses will be able to declare their own type as parameter. Unless your codebase uses raw types, this should work.

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

The limitation of this (or rather exceptions to this) will be raw types and events of other types of events, which can allow other parameter types.

Pornocracy answered 5/11, 2018 at 5:13 Comment(3)
Thank you! It seemed I had some gaps with my understanding of type parameters, which your code helped clear upRoa
That does not guarantee that a subclass's intersect method will have its own type as parameter. The following compiles: class AnotherSubClassEvent extends Event<SubClassEvent> { boolean intersect(SubClassEvent object) { return true; } }Dislocate
@Dislocate Of course it doesn't guarantee. With an overridden method in Java, though, I believe this is the closest you can get to allowing subclasses to use a different, but bounded parameter types. Without this, I believe the answer is 'no way'. But I should have pointed out this limitation too - will edit. ThanksPornocracy
D
0

This is not possible to do in Java. Consider you have your subclass SubClassEvent that implements the method boolean intersect(SubClassEvent e2). Then if it has a further subclass SubSubClassEvent extends SubClassEvent, it will inherit the method boolean intersect(SubClassEvent e2) from SubClassEvent, based on how inheritance works in Java.

SubSubClassEvent does not have to override the method since the method is non-abstract in its superclass SubSubClass. But even if SubSubClassEvent wanted to override the method, it must override it with the signature boolean intersect(SubClassEvent). If it implemented a method with the signature boolean intersect(SubSubClassEvent), it would not be considered an override of the method boolean intersect(SubClassEvent) from its superclass, under Java method overriding rules.

Therefore, SubSubClassEvent is a subclass of Event whose intersect method does not take its own type as a parameter type, violating your condition.

Dislocate answered 31/12, 2018 at 4:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.