首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >YAIC (又一次继承混乱)

YAIC (又一次继承混乱)
EN

Stack Overflow用户
提问于 2011-10-29 00:47:27
回答 4查看 75关注 0票数 0

我相信这类问题每天都会被问到,但我很难理解为什么这个哺乳动物对象被实例化为一只猫,并报告它的名字是Morris。然而,与大多数猫不同的是,它没有9条生命。如果对象不是猫,为什么它报告自己的名字是Morris?

代码语言:javascript
复制
class Mammal  {
    int temp;
    String name = "George";

    public Mammal() {
        temp = 98;
    }

    public String getName() {
        return name;
    }
}

class Cat extends Mammal {
    int lives;
    String name = "Morris";

    public Cat() {
        lives = 9;
    }

    public String getName() {
        return name;
    }
}

public class Inheritance {
    public static void main(String[] args) {
        Mammal mm = new Cat();
        System.out.println("Mam Temp:" + mm.temp);
        //System.out.println("Cat Lives:" + mm.lives);        <-- error
        System.out.println("Mam Name:" + mm.getName());  
    }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-10-29 00:54:17

这里有两个相关但具体分离的概念。

  1. 对象的运行时类型。
  2. 变量的静态(和运行时)类型。

对象的运行时类型将决定它在运行时的行为方式。它由您在使用new关键字时调用的构造函数决定。

变量的静态类型指示代码如何与该变量(以及它引用的对象)交互或引用该变量。它由您在声明变量(或字段、参数等)时指定的类型决定。

在本例中,变量的静态类型是Mammal,而它所指向的对象的运行时类型是Cat。因此,虽然它在运行时的行为类似于Cat,并将其名称显示为“Morris”,但在编译时,编译器只知道它是一个Mammal,不能引用lives变量(该变量是在Cat中定义的,而不是在Mammal中定义的)。

票数 3
EN

Stack Overflow用户

发布于 2011-10-29 00:50:31

因为该变量是在Mammal mm = new Cat();行中设置的Mammal类型。Mammal类不包含变量lives,因此它抛出错误。但是,如果执行((Cat)mm).lives,应该会得到正确的结果,因为您将mm变量强制转换为Cat类型(它被初始化为该类型)。

编辑

此外,您还覆盖了Cat类中的getName()方法,该方法“隐藏”了Mammal类中的方法。您将mm创建为一个类型Mammal,但实际上它是一个Cat,因此对mm上的getName()方法的调用将调用子方法getName(),后者返回"Morris"而不是"George"

票数 2
EN

Stack Overflow用户

发布于 2011-10-29 00:52:21

您创建了一个Cat实例,但您将其视为一个MammalMammal.lives不存在,这就是当您尝试打印mm.lives时出现错误的原因。

顺便说一句,这是一个很好的例子,说明了为什么继承可能是危险的,应该谨慎使用。猫和哺乳动物是通过继承紧密耦合在一起的,所以你必须理解这两个类以及它们是如何交互的,以便理解处理Cat的代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7932262

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档