Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Calling function in "this" class rather than a subclass (analog to "super")

Is it possible in Java to invoke an overridable method in such a way that it always executes the "locally defined" version rather than an overridden version from a subclass? I.e. is there an analog to super that refers to this class, rather than the super class?

Let me give a code example to hopefully make it clear what I'm trying to do:

class A {
    void foo() {
        System.out.println("Foo from A");
    }

    void bar() {
        foo();  // <-- This is the important line!
    }
}

class B extends A {
    @Override
    void foo() {
        System.out.println("Foo from B");
    }
}

If I do new B().bar(), it will call the bar() method defined in A, which calls foo() as overridden in B to print "Foo from B".

Is there a way that I can force the bar() method to call the foo() method as defined in A rather than B? Just like I can use super.foo() in B to call the foo() method as defined in A? Unfortunately using this.foo() still calls the version of the subclass. Even something like ((A) this).foo() or A.this.foo() doesn't work.

Clearly, I could simply define a private or final version of foo() in A and call that instead. But I am hoping for a solution, where all I do is change the "important line" in the code sample above to a different way of invoking foo() to have it print "Foo from A", preferably without some trick like reflection.

like image 378
Markus A. Avatar asked Aug 02 '26 04:08

Markus A.


2 Answers

Your object is a B. It isn't an A! Here's an example:

public class Apple {
    public void printColor() {
        System.out.println("I am red");
    }

    public void bar() {
       printColor();
    }
}

Then the subclass:

public class GrannySmithApple extends Apple {
    public void printColor() {
        System.out.println("I am green");
    }
}

GrannySmithApples are green, always (unless they are rotten, but that's a whole other can of bananas)! Once you have a GrannySmithApple, it's not an Apple anymore, except in the sense that you can do all the same things with it that you could a regular Apple (printColor, eat, etc.) Make sense? And anything that hasn't changed between the conversion from regular Apple to GrannySmithApple is obviously still the same.

like image 68
durron597 Avatar answered Aug 04 '26 18:08

durron597


You can have an "internal" foo() in A that is called.

class A {
    private void fooInternal() {
        System.out.println("Foo from A");
    }

    void foo() {
        fooInternal();
    }

    void bar() {
        fooInternal();
    }
}

class B extends A {
    @Override
    void foo() {
        System.out.println("Foo from B");
    }
}

new B().bar() will now print "Foo from A" while new B().foo() will print "Foo from B".

like image 43
maba Avatar answered Aug 04 '26 19:08

maba



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!