注意事项:阅读本文前应该先了解java的继承。本文定位为已经继承基础知识。

一:试图覆盖私有方法

先上代码

1 public classFather {2

3 private voidprint() {4 System.out.println("private print");5 }6

7 public static voidmain(String[] args) {8 Father father = newSon();9 father.print();10 }11

12 }

1 public class Son extendsFather {2

3 public voidprint() {4 System.out.println("public print");5 }6 }

运行father的main方法,我们所期望的输出是public print,但是由于private方法默认为final方法,而且对导出子类是屏蔽的,在这种情况下,子类中的print就是子类中的一个新方法,并非是覆盖了父类的print方法,而且在子类的print方法上是无法加入@override注解的

结论:private方法无法被覆盖重写。

二:在一个构造器内部调用正在构造的对象的某个动态绑定方法

我们都知道,构造器的调用会从最高级的父类开始调用,然后不断反复递归下去。如果在父类的构造器中调用子类的构造方法输出变量,会发生什么?

1 public classFather {2

3 public voiddraw() {4 System.out.println("father draw");5 }6

7 publicFather() {8 System.out.println("father:before draw");9 draw();10 System.out.println("father:after draw");11 }12

13 }

1 public class Son extendsFather {2

3 private int number = 1;4

5 public Son(intnumber) {6 this.number =number;7 System.out.println("init number:" + this.number);8 }9

10 @Override11 public voiddraw() {12 System.out.println("son draw number:" + this.number);13 }14 }

public class MainTest extendsObject{public static voidmain(String[] args) {new Son(5);

}

}

控制台打印:

father:before draw

son draw number:0

father:after draw

init number:5

在测试中,我们new一个son同时传一个5进去,根据构造器的调用,我们知道在构造son的时候要先调用father的构造方法,而在father的构造器中,有调用draw方法。而在子类中,draw方法是将son中的number打印出来,number有一个默认的值为1,那在draw调用过程中,我们期望的输出应该是1,但实际输出的是0.

解决这一问题的关键所在是初始化的过程。在其他任何事物发生之前,分配给对象的储存空间初始化为二进制的零(你可以这样认为,number有一个默认值为1,但是在有这个默认值之前还有一个默认值为0),然后父类的构造器开始调用,再递归调用子类的构造方法,然后按照声明的顺序初始化成员变量。而在这个初始化步骤之前,一切变量都是0,或者null。

三:调用子类覆盖的父类静态方法。

1 public classFather {2

3 public staticString staticGet() {4 return "father static get";5 }6

7 publicString dynaminGet() {8 return "father dynamin get";9 }10 }

1 public class Son extendsFather {2

3 public staticString staticGet() {4 return "son static get";5 }6

7 publicString dynaminGet() {8 return "son dynamin get";9 }10 }

public class MainTest extendsObject{public static voidmain(String[] args) {

Father f= newSon();

System.out.println(f.staticGet());

System.out.println(f.dynaminGet());

}

}

控制台输出:

father static get

son dynamin get

我们期望的输出应该都是son的方法而不是father的方法,但是调用静态方法的时候是father而不是son。这是因为如果某个方法是静态的,那么它的行为就不具有多态性,静态方法是与类绑定的,而不是与单个对象相关联的。子类并不能覆盖父类的静态方法,事实上,在son中的staticGet方法上无法添加@override注解。

四:子类的域可以覆盖父类的域

1 public classFather {2

3 public int number = 3;4

5 public intgetNumber() {6 returnnumber;7 }8 }

1 public class Son extendsFather {2

3 public int number = 2;4

5 public intgetNumber() {6 returnnumber;7 }8

9 public intgetSuperNumber() {10 return super.number;11 }12 }

public class MainTest extendsObject{public static voidmain(String[] args) {

Son s= newSon();

System.out.println(s.getNumber());

System.out.println(s.getSuperNumber());

}

}

控制台输出:

2

3

如果son中的number覆盖掉father的number,那么输出的两个number都应该是2,事实上从son中得到father的number为3,这说明son中的number并没有覆盖掉father中的number。在本例中,son.number和father.number分配到了不同的储存空间。换句话来说,在son中其实包含了两个名为number的变量:它自己的和从father中继承得到的。然而在son中的number所产生的默认域并非father中的number域。因此,为了得到father中的number,必须显式地指明super.field。

java子类继承错误_java继承会犯的小错误相关推荐

  1. java犯的小错误_[Java教程]十个JavaScript中易犯的小错误,你中了几枪?

    [Java教程]十个JavaScript中易犯的小错误,你中了几枪? 0 2015-06-01 12:00:19 序言 在今天,JavaScript已经成为了网页编辑的核心.尤其是过去的几年,互联网见 ...

  2. java 继承 冒号_java继承(extends)简单介绍

    继承相信很多人都有听说过,继承是面向对象的三个基本特征之一,下面的话就一起通过简单的文章来对java继承进行一下了解吧. 继承和现实生活中的"继承"的相似之处是保留一些父辈的特性, ...

  3. java继承总结_java继承总结(二)

    java学习笔记 1.继承 关键字: extends 在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以extends只能继承一个类. eg: public class P ...

  4. java 继承关键字_Java继承

    继承的概念 继承是Java面向对象编程的基石,因为它允许创建分等级层次的类. 生活中的继承: 类的继承格式 class 父类{ } class 子类 extends 父类{ } 继承类型 需要注意的是 ...

  5. java 无法取消引用_Java的新手,并出现错误“无法取消引用int” - java

    我是java的新手,并且已经从事了一段时间,但是仍然收到错误消息:无法取消引用int.我看到了几个类似的问题,但仍然无法弄清自己的情况. 这是完整的代码: package inclass; class ...

  6. java 子类属性覆盖_java子类和父类属性重复问题

    java 子类继承 父类, 但子类中 包含和父类相同 属性 ,给子类赋值之后,父类的相同的属性值还是空的. 类定义如下: public class Person { private String na ...

  7. java子类创建过程_JAVA入门小小白学习中ing(匿名对象、封装性、继承性、子类对象的创建过程、spuer关键字(用法一))...

    小小白慢慢学习中ing 第十二天 努力努力 本日内容(匿名对象.封装性.继承性.子类对象的创建过程.spuer关键字) 1.匿名对象 创建对象的语法:Person p1 = new Person(); ...

  8. java子类怎么编译_java – 无法编译从基类实现抽象方法的子类

    编译我已经定义的基类的子类有一个问题,它有一个单独的方法,而每个子类都实现了抽象基类方法,但是 javac说他们甚至没有在子类中明确定义它们. DbModel.java(基类) package com ...

  9. java 为什么用大端_Java中的大端和小端

    Java整型的字节序是() A.Little-Endian(小端) B.Big-Endian(大端) C.由运行程序的CPU决定 D.由编译程序的CPU决定 对于大小端,我估计肯定有很多开发人员跟我一 ...

最新文章

  1. iOS -数据库网络之xml解析之远程解析XML
  2. VC++调试程序、快捷键以及Debug版本与Release版本
  3. jQuery如何实现表单的自动提示
  4. Linux下sed命令替换配置文件中某个变量的值(改变包含字符的一行的值)
  5. 『重构--改善既有代码的设计』读书笔记----Remove Middle Man
  6. knime如何连接mysql_knime怎么连接MySQL?
  7. 如何预测未来房价的发展
  8. 技术动态 | 跨句多元关系抽取
  9. shell脚本if和switch语句编写案例
  10. (19)FPGA乒乓操作
  11. mysql支持数据安全的引擎_2、MySQL常见数据库引擎及比较?
  12. Git详解之六 Git工具(转)
  13. python解析http数据包_python 3 处理HTTP 请求的包
  14. C#-Activex插件操作指南
  15. 通过互联网搜索接口更新拼写语法库的设计
  16. ctf 实验吧 围在栅栏中的爱 (最近一直在好奇一个问题,QWE到底等不等于ABC? )
  17. i7 10510u相当于什么处理器
  18. 国产智多晶FPGA下载器(调试器)的驱动安装方法
  19. @Deprecated注解
  20. 模板 2018-01-27 分解因数 分解质因数

热门文章

  1. 人工智能是用计算机模拟人的智能特别是模拟,张钹院士:人工智能是让计算机模拟人的三种功能...
  2. fseek()函数用法
  3. 使用Excel进行时间转换(附时间小知识)
  4. 四川大学计算机导论吴承恩,计算机导论 李明东.pdf
  5. css中设置了font-family: 微软雅黑没有用
  6. WooCommerce入门指南:添加新订单第1部分
  7. python计算图像的曲率
  8. Java 接口与多态 实例
  9. 云计算与大数据引领ICT的未来变革
  10. 授之以鱼,不如授之以渔