当子类对象具有父类型的引用而父类没有相同的子类方法时,则无法访问子类方法

时间:2018-07-19 06:51:58

标签: java

无法使用以下行从子类访问方法,

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

假设我在Child类中有一个方法print(),而在Parent类中有一个的方法。在这种情况下,我们无法使用上述代码行访问子类方法print()。但是请注意,如果父类中具有相同的方法print(),则可以使用上面的代码访问它。

在现实生活中可能不会出现这样的情况,但是如果我们没有在父级中定义相同的方法,则试图理解为什么我无法使用类型为Parent的子对象访问子类print()课。

示例代码如下:

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;
}

更多说明-如果我在父类中定义print()方法,则可以使用类型为Parent的对象访问子类print()方法。因此,我假设我们不能说父类型的对象只能访问父类内部定义的成员/方法。

另外,我知道我们可以通过将父类型强制转换为子类型来访问子方法。我想知道为什么我们不能在不进行强制转换的情况下访问子类方法,并且如果不在父类中定义相同的方法。

我已经编辑了问题,以确保它与另一个问题-https://getbootstrap.com/docs/4.1/components/popovers/#four-directions

没有关系

2 个答案:

答案 0 :(得分:1)

如果父级未声明方法(作为具体方法或抽象方法),则子级在父变量内部实例化时将无法使用该方法。您可以使用以下代码示例来使用它

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

其背后的解释是变量p在运行时实际上并不知道哪个子实例存储在其中(可能有多个子实例,只有一个拥有print()方法,也许您会在编译时知道Parent p中存储的对象的实际类型,但是执行是另一个世界,因此,如果p对象是Child的实例,则意味着p被键入为Child或以下类型之一子对象,则可以将其转换为((Child) p),所有方法都将被识别为子对象(因为是)。

请注意,您可以强制转换一个不具有Casteable的类,并且将具有ClassCastException。在这个具体示例中,不需要写if语句,因为我们可以确定p类型,但是在运行时有时会变得混乱,并且我们不知道存储在什么位置,因此确保了您的健康铸件变得至关重要。说到转换变量,如果您只希望Child类访问方法print而不是其子类,则可以使用

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

如果您不想强制转换子代,并且您的父类适合打印方法(并非始终是一个选项),那么您可以在父级中将其声明为具体方法,并在其中覆盖该方法孩子)

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

或者您可以在父对象中将该方法声明为抽象方法,并且所有子代方法都必须实现该方法,但是,如果必须是抽象方法,则您将无法创建父对象。

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

继续,如果父母有孩子,则孩子将拥有父母的所有方法,但只要父母有,孩子的任何方法都不会。将需要铸造。如果在子级和父级中都写入了print方法,则最低的改写方法将是执行的一种(本例中的子级)。另外,您可以使用在父级中使用“ super”实现的方法(与构造函数相同)

class Child extends Parent {

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

    int x = 20;
}

答案 1 :(得分:0)

Parent p = new Child();

您正在创建带有子类的Parent对象。因此,父对象p没有方法print()很简单。但是Child对象具有方法print(),因此,如果创建Child对象,则可以从Child类访问方法print()。

在这里,方法的优先级开始发挥作用。如果两个类都具有print()方法,则子类方法优先于父类方法。

注意:继承是单向的,而不是双向的。