Java 当子类对象具有父类型的引用且父类不具有相同的子类方法时,无法访问子类方法

Java 当子类对象具有父类型的引用且父类不具有相同的子类方法时,无法访问子类方法,java,Java,无法使用下面的行从子类访问方法 Parent p = new Child(); p.print(); 假设我在子类中有一个方法print(),而父类中没有相同的方法。在这种情况下,我们无法使用上述代码行访问子类方法print()。但是请注意,如果我们在父类中有相同的方法print(),那么我们可以使用上面的代码访问它 现实生活中可能没有这样的场景,但我试图理解,如果没有在父类中定义相同的方法,为什么我无法使用父类型的子对象访问子类print() 示例代码如下: public class Mai

无法使用下面的行从子类访问方法

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

现实生活中可能没有这样的场景,但我试图理解,如果没有在父类中定义相同的方法,为什么我无法使用父类型的子对象访问子类
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()
方法。所以我假设我们不能说parent类型的对象只能访问父类中定义的成员/方法

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


我对问题进行了编辑,以确保这与另一个问题无关-

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

Parent p = new Child(); 
if(p instanceof Child){
    ((Child) p).print();
}
这背后的解释是变量p实际上不知道在运行时存储在它里面的子实例是什么(可能有几个子实例,只有一个子实例具有
print()
方法。在编译时,您可能知道存储在
父对象p
中的对象的真实类型,但执行是另一个世界。因此,如果p对象是Child的实例,意味着p被类型化为Child或其子对象之一,您可以将其强制转换为
((Child)p)
所有的方法都会被识别,就好像一个子对象是(因为它是)

注意,您可以强制转换一个不可强制转换的类,您将有一个ClassCastException。在这个具体示例中,编写
if
语句是不必要的,因为我们确定p类型,但有时在运行时事情会变得混乱,我们不知道存储在哪里,因此确保您的强制转换的健全性成为esen谈到强制转换变量,如果你只想让类的子类访问方法print,而不是它的子类,你可以使用它

Parent p = new Child(); 
if(p.getClass() == Child.class){
    ((Child) p).print();
}
如果您不想强制转换子类,并且您的父类适合打印该方法(并非始终是一个选项),正如您所说,您可以在父类中将其声明为具体方法,并重写子类中的方法)

或者,您可以在父级中将该方法声明为抽象的,并且所有子级都必须实现它,但是您将无法创建父级的对象,只要它必须是抽象的

abstract class Parent {
    int x = 10;
    abstract void print();
}
继续,如果父对象有子对象,子对象将拥有父对象的所有方法,但只要是父对象,子对象将没有任何方法。需要一个铸件。如果在子级和父级中写入print方法,则执行的覆盖方法(在本例中为子方法)最低。另外,可以使用在父级中使用“super”实现的方法(与构造函数中的方法相同)

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

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


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

其实很简单:
Parent
没有名为
print
的方法。您正在声明
p
是父级。编译器看到了这一点,开始寻找它的
print
方法,然后。。。没有->错误。如果您现在在
Parent
中声明了它,并且像往常一样在运行时调用
Child
类中的重写方法…另一个选项是将对象强制转换为实际的子对象。Child=(Child)p;->这应该使方法也可以访问。@MalteHartwig不是重复的bcz您提到的方法是找到一种方法,在引用具有父类型时调用子方法,我们可以使用类型转换来实现。但在我的问题上,这是不同的。请仔细阅读问题。据我所知,你的问题仍然是你链接的问题的副本。仅仅否定你的问题并不会使其他答案变得无用;它仍然应该解释为什么在不使用或打开方法的情况下无法访问孩子的方法。此外,本的评论是一个很好的总结。您可以在父类型中强制转换或定义(抽象)方法。如果我在父类中定义print()方法,那么我可以使用类型为parent的对象访问子类print()方法。你会对引用和对象感到困惑。父对象甚至不知道任何子类,但当您在父引用上调用方法时,它将调用父版本或子版本,具体取决于实际对象以及子对象是否重写了该方法。实际上,子对象将能够使用它,问题是它未声明为Chil
abstract class Parent {
    int x = 10;
    abstract void print();
}
class Child extends Parent {

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

    int x = 20;
}
Parent p = new Child();