Reputation: 98
I have created a very simple program to test which method will be called when that method will be called through inheritance.
Class boo extends foo
.
Using boo
object, a method from foo
class showMe
is called. showMe
method in foo
class calls a method showText
to show the text on the screen.
boo
class overrides the showText
method and show a different text.
My prediction was that the method in foo
class will be called instead of its overridden version in boo
class. I was wrong and the method in boo
class was called. Can someone please explain me how that happened. Also, I want to know how to call the method in the foo
class even if I have a overridden method in boo
class.
boo class
public class boo extends foo
{
public static void main(String[] args)
{
boo main = new boo();
main.showMe();
}
@Override
public void showText()
{
System.out.println("Bruhhh!!!");
}
}
foo class
public class foo
{
protected void showMe()
{
showText();
}
public void showText()
{
System.out.println("Bruhhh Part 2!!!");
}
}
Upvotes: 0
Views: 97
Reputation: 288
Boo list = new Boo();
list.showText();
Foo list2 = new Boo();
list2.showText();
Foo list3 = new Foo();
list3.showText();
// Boo list4 = new Foo(); Incorrect!!
result
Bruhhh!!!
Bruhhh!!!
Bruhhh Part 2!!!
By the way, In Java Class name must start with Uppercase!!
So, How does it work? : Understand the Object and Instance in Java
In first code
Boo list = new Boo();
list.showText();
Actually, list.showText() method is called in Boo
class (All methods & data of Boo
class is instanced in Memory)
1) If there is @override showText()
, then it will be called in Boo
Class
2) If there isn't, then it will be called in parent Object
In Second code
Foo list2 = new Boo();
list2.showText();
Actually, list.showText() method is called in Boo
class but used Foo
Object
(What? it means that Boo
class must extend Foo
Class to use Foo Object!! and list2 can only call methods in Foo
Class)
1) If there is @override showText()
in Boo
, then it will be called in Boo
Class
2) If there isn't, then it will be called in parent Object
Upvotes: 1
Reputation: 3181
The method in boo was called because main
is of type boo
.
If you want it to print the one in foo
, you should change boo main = new boo();
to foo main = new foo();
Inheritance is a tree. It's easier to understand if you try to relate it to real life trees, like evolution, vehicles, professions and related branches. For example, there are many types of engineers. At first there were Engineer
, then ElectricalEngineer
, then ComputerEngineer
.
public class Engineer {
public void do() {
System.out.println("I build stuff");
}
}
public class ElectricalEngineer {
public void do() {
System.out.println("I build electronics");
}
}
public class ComputerEngineer {
public void do() {
System.out.println("I build computers");
}
}
Engineer eng = new Engineer();
ElectricalEngineer ee = new ElectricalEngineer();
ComputerEngineer ce = new ComputerEngineer();
eng.do(); // prints "I build stuff"
ee.do(); // prints "I build electronics"
ce.do(); // prints "I build computers"
// eng is of type Engineer
// ee is of type ElectricalEngineer
// ce is of type ComputerEngineer
Engineer ee2 = new ElectricalEngineer();
Engineer ce2 = new ComputerEngineer();
ee2.do(); // prints "I build electronics"
ce2.do(); // prints "I build computers"
Here, it looks like ee2
is of type Engineer
, but it actually is ElectricalEngineer
. It will call its overridden do()
method. Same with ce2
ElectricalEngineer ce3 = new ComputerEngineer();
ce3.do(); // prints "I build computers"
But if you do:
ElectricalEngineer ee3 = new Engineer();
ComputerEngineer ce4 = new ElectricalEngineer();
ComputerEngineer ce5 = new Engineer();
You'll get errors on all of them because an ElectricalEngineer
IS an Engineer. A ComputerEngineer
IS an ElectricalEngineer
. ComputerEngineer
IS an Engineer
as well. But not all Engineers
are guaranteed to be ComputerEngineer
or ElectricalEngineer
. They may be CivilEngineer
for all you know.
Upvotes: 1
Reputation: 102
if
//SuperClass
class A()
{
public void methodExample()
{
//Origional Functionality
}
}
//SubClass
class B extends A()
{
@Override
public void methodExample()
{
//New Functionality
}
}
To my knowledge, class 'B' cannot expect the origional (or more general, not-overridden) functionality from any in its superclass 'A' if 'B' has overridden that method with a new functionality. If you still need that functionality, you may want to make a method in the superclass which you do not overrun.
Upvotes: 1
Reputation: 70564
Method calls are resolved using the runtime class of the this
object, not the compile time type of the this
reference.
Therefore, when showMe()
invokes showText()
, the runtime determines the runtime class of the this
object, which is boo
, and looks for the method in that class.
The only way to invoke an overridden method is using super
in a subclass. For instance, you could do:
class boo extends foo {
@Override
public void showMe() {
super.showText();
}
to have the showMe()
method invoke the overridden super implementation.
Upvotes: 1
Reputation: 19603
It's not entirely clear from your question what exactly you're looking for, but I think this covers most of your cases:
public class boo extends foo
{
public static void main(String[] args)
{
//Create & use a "foo" object
System.out.println("Use foo's showText()");
foo main1 = new foo();
main1.showMe();
System.out.println("=====================");
//Create & use a "boo" object (but pass it around as a "foo")
System.out.println("Use boo's showText()");
foo main2 = new boo();
main2.showMe();
System.out.println("=====================");
//Create & use a "boo" object
System.out.println("Use boo's showText()");
boo main3 = new boo();
main3.showMe();
}
@Override
public void showText()
{
System.out.println("Bruhhh!!!");
super.showText();
}
}
The version of showText
that gets called is dependent on the type of main
. If you look at the three examples in the code above, the new
statement that creates the object controls what showText
will get called. It doesn't matter if you pass the object around as a foo
or boo
; polymorphism will ensure that the showText
on the actual type of the object you created will be called.
To answer your other question, you can user the super.method()
syntax to call a parent class method from a child class.
Upvotes: 1
Reputation: 2034
Except from Alex's answer, if you still want to call foo's method from boo while instantiating only boo, you will have to create another method in boo
. So your boo class becomes:
public class boo extends foo
{
public static void main(String[] args)
{
boo main = new boo();
main.showMe();
}
@Override
public void showText()
{
System.out.println("Bruhhh!!!");
}
public void showFooText(){
super.showText();
}
}
calling showFooText()
will display text from foo.
Upvotes: 1