Deep
Deep

Reputation: 98

Method call using Inheritance

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

Answers (6)

Daniel Park
Daniel Park

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

Alex
Alex

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

evn
evn

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

meriton
meriton

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

Brent Writes Code
Brent Writes Code

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

Jaskaranbir Singh
Jaskaranbir Singh

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

Related Questions