Understanding inheritance in Java

Please don't be angry if my question is stupid)

I have some code:

public class LinkageTest { 

public static class Parent { 

    public void test() { 
        System.out.println("parent::test"); 
    } 
} 

public static class Child extends Parent { 

    public void test() { 
        System.out.println("child::test"); 
    } 
} 

public static class Tester { 

    public void test(Parent obj) { 
        System.out.println("Testing parent..."); 
        obj.test(); 
    } 

    public void test(Child obj) { 
        System.out.println("Testing child..."); 
        obj.test(); 
    } 
} 

public static void main(String[] args) { 
    Parent obj = new Child(); 
    Tester t = new Tester(); 
    t.test(obj); 
} 

      

}

When I run it, the following line is printed:

Testing parent... child::test

I can't figure out why the test

c method Parent

is called when we have an instance Child

? Can anyone help me with this?

+3


source to share


5 answers


1) The class Child

overrides (overrides) the method test

. (Polymorphism)

2) In the class, Tester

methods test(Parent obj)

and are test(Child obj)

overloaded. When you call a method, a method with the appropriate type is selected.



3) at the moment the t.test(obj)

variable obj

has an explicitly defined type Parent

, so the appropriate method will be selected and "Testing the parent ..." will be printed.

4) at the moment in time, the obj.test()

test method of the class will be called Child

, since this is polymorphism

+3


source


You create a Child object using a Parent link like

Parent obj = new Child(); // obj has Child and Parent both type
System.out.println(obj instanceof Parent); // it returns true

      

And matrod questioning the parents of the parents,

public static class Child extends Parent{ 
    public void test(){ //overriding here
        System.out.println("child::test"); 
    } 
}

      

when you call t.test (obj) method

    public static void main(String[] args){ 
    Parent obj = new Child();
    Tester t = new Tester();
    t.test(obj); // obj created by Parent reference  
}

      



So it catches:

public void test(Parent obj){ // catches here
        System.out.println("Testing parent..."); // Here is your first output
        obj.test(); 
    }

      

then obj has an overridden test method , so it calls

public static class Child extends Parent{ 
    public void test(){ // overridden method first priority
        System.out.println("child::test"); // Here is your second output
    } 
} 

      

if you change the name of the test method of the Child class then it calls the test method of the parent class and the output will be

Testing parent...
parent::test

      

+1


source


Because you are calling

Parent obj = new Child();
t.test(obj); //object created by Parent reference

      

This is obj from parent , so it will call "Testing parent" from the Tester class.

Then, thanks to polymorphism , it will also call "child :: test" from the Child class, because it is overridden.

Try to call:

Child obj = new Child();
t.test(obj);

      

And you will see:

"Testing child..."
"child::test"

      

You should also place the @Override method in the test () method of the Child class.

+1


source


This is because you are calling the tester method with the Parent argument type. But the actual object is inside, the concrete implementation is Child. Perhaps these are not good words to describe, I hope you understand.

If you called typeof (obj) it will return Parent. If you are debugging your application, you will see that the method called is the one that has a parent argument, because you are passing an argument that is of type parent.

The more specific the Object is Child (in fact you can draw obj to Child and it will work fine because it is a child from the inside). And when you do obj.test (), it will call the method from child because it is being overridden by the child.

0


source


The decision to name Tester.test(Parent obj)

is done at compile time . At compile time, the compiler must choose the method signature (not the implementation, but the signature). The compiler sees two methods with the same name but different signatures, it can only choose the signature Parent

because you declared Parent obj

. That is why in the last byte code it will be represented as

find method test(Parent) in object t and execute it

      

The naming decision Child.test

is executed at runtime . At compile time, the compiler only finds one signature for the method test (despite the two different implementations in Parent / Child, the signature is the same). Thus, the actual implementation of both methods in the Tester class will be:

find method test() in object obj and execute it

      

So, even though the Tester.test (Parent) method is called, it will still try to find the test method in the passed object, once you pass the child-child version it will actually be executed.

0


source







All Articles