Child class method cannot be accessed when a child class object has a reference of parent type and parent class dont have the same child class method [duplicate]

喜夏-厌秋 提交于 2021-02-19 14:55:25

问题


Could not access methods from child class using the below line,

Parent p = new Child(); p.print();

Suppose I have a method print() inside Child class and the same method is NOT there in the Parent class. In this scenario we cannot access child class method print() using the above line of code. But note that if we have the same method print() in the parent class then we can access it using the above code.

There might not a real life scenario like this but trying to understand why I am not able to access child class print() using a child object which is of type Parent if we dont have the same method defined in the parent class.

Sample code is below:

public class Main {

    public static void main(String[] args)
    {

        Parent p = new Child();
        p.print(); //Compiler throws an error saying "cannot resolve print method".


    }

}

class Parent {
    int x = 10;


}

class Child extends Parent {

    void print(){
        System.out.println("Child");
    }

    int x = 20;
}

More explanation - if I define the print() method inside the parent class then I can access the child class print() method using an object of type Parent. So I assume that we cannot say that an object of type parent can access only members/methods defined inside a parent class.

Also , I know that We can access the child method by casting the parent type to the child type. I am wondering why we cannot access the child class method without casting and if we dont define the same method in the parent class .

I have edited the question so as to make sure that this has no relation with the other question - Calling a subclass method from superclass


回答1:


When the parent hasn't the method declared (as a concrete or abstract method) the child won't be able to use that method when is instanced inside of a parent variable. You can use the following code sample in order to use it

Parent p = new Child(); 
if(p instanceof Child){
    ((Child) p).print();
}

The explanation behind this is that the variable p doesn't actually know what child instance is stored inside it in runtime(there could be several children and none but one have the print() method. Maybe you will know the real type of the object stored in Parent p in compilation time but the execution is another world. So if the p object is an instance of Child, meaning that p is typed as Child or one of its children, you can cast it ((Child) p) and all the methods will be recognized as if a child was (because it is).

Attention, you can cast a class not Casteable and you will have a ClassCastException. In this concrete example writting the if sentence wouldn't be necessary because we are certain about the p type, but some times in runtime things get messy and we don't know what is stored where so ensuring the sanity of your castings becomes esential. Talking about casting variables, if you only want the class Child to access to the method print but not its subclasses you can use

Parent p = new Child(); 
if(p.getClass() == Child.class){
    ((Child) p).print();
}

If you don't want to cast the children and your parent class is suitable to have the method print (not allways an option), as you said you can declare it as a concrete method in the parent and override the method in the child)

class Parent {
    int x = 10;
    void print(){
        System.out.println("Parent");
    }
}

Or you can declare the method as abstract in the parent and all the children will have to implement it, but then you won't be able to create objects of the parent as long as it will have to be abstract.

abstract class Parent {
    int x = 10;
    abstract void print();
}

Resuming, if a parent has a child, the child will have all the methods of the parent but as long as is the parent, will have none of the child's methods. A casting will be needed. If the method print is writen in the child and in the parent, the lowest overwritting method will be the one executed (the child one in this case). As an extra, you can use a method implemented in the parent using 'super' (the same that in constructors)

class Child extends Parent {

    void print(){
        super.print("Child");
    }

    int x = 20;
}



回答2:


Parent p = new Child();

you are creating the Parent object with child class. So, it is simple that the Parent object p doesn't have the method print(). But the Child object has the method print(), so if you create a Child object , then you can access the method print() from the Child class.

Here the precedence of methods comes into play. If you have print() method in both classes, then the child class method has the precedence over the parent class method.

NB: The inheritance is unidirectional not bidirectional.



来源:https://stackoverflow.com/questions/51416125/child-class-method-cannot-be-accessed-when-a-child-class-object-has-a-reference

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!