为什么在子类中不重写超类的实例变量

当我们在父类和子类中创建一个具有相同名称的变量,并尝试使用持有子类对象的父类引用访问它时,我们会得到什么?

为了理解这一点,让我们考虑下面的示例,其中在ParentChild类中声明一个具有相同名称的变量x

class Parent {// Declaring instance variable by name `x`String x = "Parent`s Instance Variable";public void print() {System.out.println(x);}
}class Child extends Parent {// Hiding Parent class's variable `x` by defining a variable in child class with same name.String x = "Child`s Instance Variable";@Overridepublic void print() {System.out.print(x);// If we still want to access variable from super class, we do that by using `super.x`System.out.print(", " + super.x + "\n");}
}

现在,如果我们尝试使用以下代码访问x ,将打印什么System.out.println(parent.x)

Parent parent = new Child();
System.out.println(parent.x) // Output -- Parent`s Instance Variable

一般而言,我们会说Child类将覆盖Parent类中声明的变量,并且parent.x将给我们任何Child's对象所持有的东西。 因为在方法上进行相同类型的操作时发生的是同一件事。

但是实际上并非如此, parent.x将为我们提供在Parent类中声明的Parent实例变量的值,但是为什么呢?

因为Java中的变量不遵循多态性,所以重写仅适用于方法,而不适用于变量。 并且,当子类中的实例变量与父类中的实例变量具有相同的名称时,则从引用类型中选择该实例变量。

在Java中,当我们在Child类中使用已经用于在Parent类中定义变量的名称定义变量时,Child类的变量将隐藏父类的变量,即使它们的类型不同。 这种概念称为可变隐藏。

换句话说,当子类和父类都具有相同名称的变量时,子类的变量将隐藏父类的变量。 您可以在文章什么是Java中的变量阴影和隐藏中阅读有关变量隐藏的更多信息。

变量隐藏与方法覆盖不同

尽管变量隐藏看起来像是覆盖变量,类似于方法覆盖,但事实并非如此,但覆盖仅适用于方法,而隐藏适用于变量。

方法覆盖的情况下,覆盖方法完全替代了继承的方法,因此当我们尝试通过持有子对象来从父对象的引用访问该方法时,将调用子类中的方法。 您可以在“方法重载与方法重载”一书中了解有关重载以及被重载的方法如何完全替代继承的方法的知识,以及为什么要遵循方法 重载 规则 。

但是在变量隐藏中,子类将隐藏继承的变量而不是替换它们,这基本上意味着子类的对象包含两个变量,而子变量则隐藏了父变量。 因此,当我们尝试从Child类中访问变量时,将从子类中访问该变量。

如果我简化了示例8.3.1.1-3。 隐藏 Java语言规范 的实例变量 :

当我们在Child类中声明一个具有相同名称(例如x作为Parent类中的实例变量的变量时,

  1. 子类的对象包含两个变量(一个是从Parent类继承的,另一个是在Child本身中声明的),但是子类变量隐藏了父类的变量。
  2. 由于声明xChild皮的定义xParent ,类的声明中Child ,简单名称x总是指到外地类中声明的Child 。 而且,如果Child类方法中的代码想要引用Parent类的变量x ,则可以将其作为super.x来完成。
  3. 如果我们尝试访问ParentChild类之外的变量,则从引用类型中选择实例变量。 因此,以下代码中的表达式parent2.x给出了属于父类的变量值,即使它持有Child的对象,但((Child) parent2).x可以从Child类访问该值,因为我们进行了相同的转换参考Child

实例变量

为什么以这种方式设计可变隐藏

因此,我们知道实例变量是从引用类型而不是实例类型中选择的,并且多态性不适用于变量,但是真正的问题是为什么? 为什么变量被设计为跟随隐藏而不是覆盖。

因为如果我们在子类中更改其类型,则变量覆盖可能会破坏从父级继承的方法。

我们知道每个子类都从其父类继承变量和方法(状态和行为)。 想象一下,如果Java允许变量覆盖,并且我们在子类中将变量的类型从int更改为Object 。 它将破坏使用该变量的任何方法,并且由于子级已从父级继承了这些方法,因此编译器将在child级中给出错误。

例如:

class Parent {int x;public int increment() {return ++x;}public int getX() {return x;}
}class Child extends Parent {Object x;// Child is inherting increment(), getX() from Parent and both methods returns an int // But in child class type of x is Object, so increment(), getX() will fail to compile. 
}

如果Child.x覆盖Parent.xincrement()getX()工作? 在子类中,这些方法将尝试返回错误类型的字段的值!

如前所述,如果Java允许变量覆盖,则Child的变量不能替代Parent的变量,这将破坏Liskov替代性原则(LSP)。

为什么从引用类型而不是实例中选择实例变量

如JVM内部如何处理方法重载和覆盖中所述 ,在编译时,覆盖方法调用仅从引用类处理,但是所有覆盖的方法在运行时都使用vtable被覆盖方法替代,这种现象称为运行时多态性。

同样,在编译时,变量访问也从引用类型处理,但是正如我们所讨论的,变量不遵循重写或运行时多态性,因此它们在运行时不会被子类变量替代,仍然引用引用类型。

一般而言,没有人会建议隐藏字段,因为这会使代码难以阅读并造成混乱。 如果我们始终坚持下去,这种混乱就不会出现。
创建POJO并通过将它们声明为私有并封装我们的字段的一般准则,并根据需要提供getter / setter,以便在该类之外看不到变量,并且子类无法访问它们。

您可以在此Github存储库中找到完整的代码,请随时提供宝贵的反馈。

翻译自: https://www.javacodegeeks.com/2018/11/instance-variable-class-overridden-class.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/345135.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【渝粤题库】陕西师范大学200681C语言程序设计 作业(高起专、高起本)

一、单选题 1.有如下程序段,其执行后的输出结果为( )。 main() {int i8; while(i>1) {–i; printf(“%d”,i–);} } A. 753 B. 7531 C. 8642 D. 864 2.在下列的数组定义中,哪一个有语法错误(…

【渝粤题库】陕西师范大学201041德育论 作业(专升本)

《德育论》作业 一、单选题 1.德育过程的实质是(  )  A.将学生的思想品德认识转化为品德行为   B.提高学生自我教育、自我修养的自觉性  C.提高学生对客观世界的认识  D.教育者将一定社会的思想道德规范转化为受教育者个体的思想品德 2.大众传媒的…

【渝粤题库】陕西师范大学201661英语阅读(二)作业(高起专)

陕西师范大学 内 部 题 库 教育 (yuyueshool) 编制 《阅读(二)》作业 I.Words DIRECTIONS: Read the sentence given with each word and choose the best meaning for it. 1.injure Wooden spears or swords should be used on…

cocos lua调用java_【Tech-Lua】Cocos-2dx-Lua调用java的小白教程(三)

上周五下班前,打包成功了。我很高兴,周六去踢场足球,周日去现场看了最后一分钟掉球的恒大,度过了一个愉快的周末。然后,噩梦的周一开始了。我再次打包,打算打包就安装,但结果是失败的。为何&…

github上java项目_GitHub上10,000个最受欢迎的Java项目-以下是他们使用的顶级库

github上java项目随着Java开发人员使用既成熟又高度发展的语言来工作,无论何时编写新代码,我们都将面临一个持续的困境–使用大家都在谈论的热门新技术,或者坚持使用久经考验的库? 由于Java应用程序的很大一部分是商业性质的&…

【渝粤题库】陕西师范大学202071 统计学 作业(专升本、高起本)

《统计学》作业 一、单项选择题 1.对于占全国彩电总产量绝大比重的彩电企业进行生产基本情况全面调查这是( )   A、典型调查  B、普查    C、重点调查 D、抽样调查 2.某地进行国有商业企业经营情况…

【渝粤题库】陕西师范大学202861 发展心理学 作业(专升本)

《发展心理学》作业 一、名词解释 发展心理学正强化心理社会的合法延缓期复演说负强化学习障碍图式溶血症抓握反射应答性行为观察学习多动症 二、填空题儿童动作发展的顺序是(  )、 ( )、从大肌肉到小肌肉。(  &…

char java 回文_LeetCode刷题笔记(Java)---第1-18题

题目来自LeetCode文章目录全部章节1-18题19-40题41-60题61-80题81-100题101-120题121-140题1.两数之和2.两数相加3.无重复字符串的最长子串4.寻找两个有序数组的中位数5.最长回文子串6.Z 字形变换7.整数反转8.字符串转换整数 (atoi)9.回文数10.正则表达式匹配11.盛最多水的容器…

使用PostgreSQL使用Spring Boot和JPA构建基本应用

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。 每个不平凡的应用程序都需要一种保存和更新数据的方法:可通过HTTP访问的资…

【渝粤题库】陕西师范大学210001儿童心理学 作业(高起专、高起本)

《儿童心理学》作业 一、填空 1、研究儿童心理必须遵循的原则是______ 、 _______ 、。 2、新生儿最基本的无条件反射是 、 ________ 、。 3、学前儿童掌握实物概念的特点是以_______为主,以_______为主。 4、感觉既是一种______现象,又是一种_______现象…

【渝粤题库】陕西师范大学210033 劳动法与社会保障法作业

《劳动法与社会保障法》作业 一、单项选择题 1.职工李某1985年8月进某皮鞋厂工作,二年后因失恋精神失常,经当地区精神病防治院诊断为精神分裂症,并经住院治疗,以后也常有病假。1995年9月李某以要调换新单位为由申请辞职。在单位制…

【渝粤题库】陕西师范大学292969 会计学 作业 (专升本、高起本)

陕西师范大学 内 部 题 库 教育 (yuyueshool) 编制 《会计学Ⅱ》作业 一、名词解释 1、会计核算 2、会计主体 3、可比性 4、会计监督 5、持续经营 6、一致性 7、复式记账 8、会计期间 9、谨慎性 10、财产清查 11、权责发生制 12、流动资产 二、填空 1、…

百分制转化为五级制java_javav 的日志-编写存储过程,将百分制成绩,转换成绩等级’A’,’B’,’C’,’D’,’E’...

要求;存储过程要有输入和输出create procedure chengji( in n int , out result varchar )begindeclare result varchar(20);set ntruncate(rand()*100,0);casewhen n>90 thenset resultA;when n>80 thenset resultB;when n>70 thenset resultC;when n&…

guava 并发_使用Guava对并发应用程序进行基于对象的微锁定

guava 并发编写并发Java应用程序时最令人讨厌的问题之一是对线程之间共享的资源的处理,例如Web应用程序的会话和应用程序数据。 结果,如果应用程序的并发级别很低,许多开发人员选择根本不同步这些资源。 例如,不太可能同时访问会话…

【渝粤题库】陕西师范大学500001 理论力学 作业(专升本)

《理论力学》作业 一. 填空 在平面极坐标系中,速度的径向分量为______ ,横向分量为_____,加速度的径向分量为_____,横向分量为_____。在平面自然坐标系中,的方向为______,,质点的切向加速度为_…

java数组按照大小排列_Java怎么让数组中元素按照牌值从小到大的顺序排列

展开全部你说的这些牌是用数组来存放的,所以有些麻烦。直接复制运行,更改牌的62616964757a686964616fe58685e5aeb931333332643838数量测试,有不懂的再问我package test;import java.util.Arrays;import java.util.Random;public class DaoTes…

【渝粤题库】陕西师范大学700005 遗传学

《遗传学》作业 一、名词解释 1.杂种优势 2. 外显率 3.罗伯逊易位 4.上位效应   5.互补测验 6.表现度 7.平衡…

通过示例了解Apache Ignite Baseline拓扑

点燃基准拓扑或BLT表示群集中的一组服务器节点,这些服务器节点将数据持久存储在磁盘上。 其中,N1-2和N5服务器节点是具有本机持久性的Ignite集群的成员,这些集群使数据能够持久存储在磁盘上。 N3-4和N6服务器节点是Ignite群集的成员&#x…

国家开放大学2021春1032成本管理题目

教育 教育 试卷代号: 1032 2021年春季学期期末统一考试 成本管理 试题 2021年7月 一、单项选择题(本类题共20分,每小题2分) 1.交互分配法一般在( )分配中使用。 A.直接材料费用 B.辅助生产费用 C.直接工资 D.在产品成本 2.采用品…

java synchronized 参数_synchronized 参数的理解

synchronized 是java中用来同步的方法,详细的就不介绍了。synchronized的用法为:synchronized(锁){代码块}这个锁是什么呢,我看了很多说法但没有一个能讲清楚的。通过一段时间的使用后逐渐发现了一些synchronized使用的规律使用synchronized是…