繁体   English   中英

为什么我不能使用引用子类型实例的父类型的引用来调用子类方法?

[英]why can't I call a subclass method using a reference of a parent type that refers to an instance of a sub-type?

我正在学习 Java,同时试图了解继承。 我无法弄清楚为什么子类 walk() 中的重写方法被执行但其他 xyz() 方法没有执行。

   class Person{
     public void walk() { System.out.println("walking like a person "); }
   }

   public class Soldier  extends Person{
    @override
    public void walk() { System.out.println("marching like a  soldier "); }
    public void xyz()   { System.out.println("xyzng like a pro"); }

    public static void main(String[] args) {

        Person sp = new Soldier();
        sp.walk(); 
        sp.xyz();
     }
   }

这是我的问题,如果以下方法调用工作正常并调用 Soldier 方法 walk,

    sp.walk(); 

为什么编译器会抱怨 this 调用?

    sp.xyz();

在编译时,父类引用“sp”只能看到其中的方法。 如果你想访问为 ((Soldier) sp).xyz()

您可能想看看这个答案

基本上, xyz方法是在Person的子类中定义的,在一般情况下,编译器无法知道(也不应该知道)引用的实例是Soldier还是其他未定义xyz方法的子类。

在 Java 中,“对象”本身不是值——它们必须始终通过引用进行操作; 当你创建一个对象时,你会得到一个引用; 当你访问一个字段或调用一个方法时,你是通过引用来完成的。 当您将一个引用分配给另一个引用时,它会复制该引用,因此您有多个指向同一对象的指针。

您的问题是当Soldier对象存储在Person引用中时为什么无法访问 Soldier.xyz() 。 答案是“多态性”和“静态类型”的交集。 因为 Java 在编译时是静态类型的,所以您可以从编译器获得某些保证,但您必须遵守规则作为交换,否则代码将无法编译。 在这里,相关的保证是子类(例如Soldier )的每个实例都可以用作其超类(例如Person )的实例。

请看一下这个它在线程中有更详细的解释作为真正理解继承的教程指南请看一下这篇文章

这很清楚。 因为您对 object(sp) 的引用属于 Person 类型,这意味着 sp 仅包含 Person 的所有属性和方法。 即使你得到了 Soldier 的实例,但你的引用还来自 Person 类型。

  • Person是一个类。
  • sp是一个对象,它是Person的一个实例
  • Person类没有名为xyz()的方法,因此sp.xyz()无法正常工作。

在此处输入图像描述

(你有一个错字,我们使用@Override ,而不是@override

在编译时,IDE 只知道静态 Object 类型是 Person 类。 您可以在此处查看编译时参考规则: https ://www.cs.cornell.edu/courses/JavaAndDS/files/compiletimeReferenceRule.pdf

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM