Java OOP – Override Method with Subclass as Argument

designjavaobject-oriented-design

When you want an overrided method to take as argument a subclass of the argument of the overridden method, you usualy accomplish that with generics (as discussed in Template pattern with varying input type in overridden method). An example of that can be seen in my methodA of the class Parent and Child

I am wondering if it is possible to do the same thing with a method that takes as argument an object of the class itself (my methodB)

abstract class Super {}

class Sub extends Super {}

abstract class Parent<S extends Super> {
    abstract void methodA(S argument);
    abstract void methodB(Parent<S> parent);
}

public class Child extends Parent<Sub> {
    @Override
    void methodA(Sub argument) {}

    @Override
    void methodB(Child child) {}
}

In the code above methodB in Child does not override methodB from Parent.

I could of course use casting in methodB from Child as in:

public class Child extends Parent<Sub> {
    @Override
    void methodB(Parent<Sub> child) {
        (Child) child
    }
}

But as a general rule I try to avoid casting as much as possible.

Is it possible to have an overrided methodB in Child (with signature @Override void methodB(Child child))? If so, what would the signature of methodB (in Parent) look like?

Best Answer

Let's assume what you want was possible. Let's make another child class:

public class Child2 extends Parent<Sub> {
    @Override
    void methodA(Sub argument) {}

    @Override
    void methodB(Child2 child) {}
}

Now, what if I have this:

Parent<Sub> child = new Child();
Parent<Sub> child2 = new Child2();
child.methodB(child2);

The child is a pointer of type Parent<Sub>, so it's methodB is expecting an argument of type Parent<Sub> - which is OK because child2 is also a pointer of type Parent<Sub>. But the object child refers to is of type Child, which it's methodB only accepts argument of type Child - and child2 is pointing to an object of type Child2 - which is not a subclass of Child...