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.
foo()
always invokes instance method of the class used innew ...
statement.In short I think that the answer to your question is NO, it can't be done. It would prevent you from overriding parts of behaviour completely.
As far as I know, a
B
object will always call its ownfoo()
method. With that said,B.foo()
can be defined to call the superclass'foo()
method. For example, you could defineB
as follows:And doing so will have
B
callfoo
fromA
. But doing so will have it always do so.You can have an "internal"
foo()
in A that is called.new B().bar()
will now print "Foo from A" whilenew B().foo()
will print "Foo from B".Either make your methods static (baadddddd), either change your design.
Indeed, it makes no sense to provide the default behavior for a subclass that it is defined to adapt itself to the concerned method.
As your
foo()
method seems to vary, you may implement a Strategy Pattern like this:this
references "this object", not "this class".That means if you have an object
B
that extendsA
, when it executes a method in the superclassA
that mentionsthis
, it will actually point to the instance ofB
, so will execute the method onB
.You can think of the method in
A
as a default method. If the method is overridden in your actual objectB
, then it will always be called instead.I suggest you change your design and use composition instead of inheritance: that would ensure a clear separation of concern, and make your code a lot easier to understand and test.
Your object is a
B
. It isn't anA
! Here's an example:Then the subclass:
GrannySmithApple
s are green, always (unless they are rotten, but that's a whole other can of bananas)! Once you have aGrannySmithApple
, it's not anApple
anymore, except in the sense that you can do all the same things with it that you could a regularApple
(printColor
,eat
, etc.) Make sense? And anything that hasn't changed between the conversion from regularApple
toGrannySmithApple
is obviously still the same.