dadus33
dadus33

Reputation: 125

Making an overriden method's super refer to the superclasss super

I know the title might sound a bit weird, but that's exactly what I'm willing to do. Simply explained: Class A is a sub-class of class B, and class B is also a sub-class of class C.

Now, all those classes contain the method m(). In my A class, the only one I have access to, as the others are only available at runtime, I override the B class's m() method. However, the m() method of the B class contains a call to the m() method of it's own superclass (that is C), and, although I made some modifications to it, I eventually also have to call that method.

I have searched for a while and I've heard that in similar situations this would be impossible as it would "break encapsulation", and I really understand why. However, in my case, I'm doing it all inside an overriden method, so is there any way I can actually make it so it would work this way? Thanks!

EDIT: Ahm, I think I didn't explain quiet well. I'm only overriding the method from the B class in my C class. From there, inside my method in the C class, I need to call the m() method not of the B class (which would work for super.m()) but for the C class.

Here's my actual code if it might help:

    @Override
public void m() {

    if(this.au() && this.getGoalTarget() != null && this.vehicle instanceof EntityChicken) {
        ((EntityInsentient) this.vehicle).getNavigation().a(this.getNavigation().j(), 1.5D);
    }

    try {
        ((EntityMonster) this.getClass().getSuperclass().getSuperclass().getConstructor(World.class).newInstance(this.world)).m();
    }catch(InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e){
        e.printStackTrace();
    }

}

Upvotes: 2

Views: 91

Answers (2)

fps
fps

Reputation: 34460

If you can't use inheritance, then you should give the decorator pattern a chance.

In the motivation section:

...sometimes (e.g., using external frameworks) it is not possible, legal, or convenient to modify the base class.

In your case, you could use the decorator pattern to add functionality to the C class (the class that inherits from B):

class A {
    public void m() {
        System.out.println("A");
    }
}

class B extends A {
    public void m() {
        System.out.println("B");
    }
}

class C extends B {

    private final A base;

    public C(A base) { // pass other needed arguments
        this.base = base;
    }

    public void m() {
        this.base.m(); // instead of super.m()
        System.out.println("C");
    }
}

You'd need to instantiate C as follows:

A base = new A();
C c = new C(base);

And then:

c.m();

Which should print:

A
C

Upvotes: 2

wake-0
wake-0

Reputation: 3968

Do you want to call it this way?

public class C {

    public void m() throws IllegalAccessException, InstantiationException {
        System.out.println("C");
    }
}

public class B extends C {
    @Override
    public void m() throws IllegalAccessException, InstantiationException {
        super.m();
        System.out.println("B");
    }
}

public class A extends B {
    @Override
    public void m() throws IllegalAccessException, InstantiationException {
        ((C) this.getClass().getSuperclass().getSuperclass().newInstance()).m();
        System.out.println("A");
    }
}

Upvotes: 0

Related Questions