Java编程关于子类重写父类方法问题的理解
作者:蝉蝉 发布时间:2022-05-25 05:00:32
子类重新实现父类的方法称重写;重写时可以修改访问权限修饰符和返回值,方法名和参数类型及个数都不可以修改;仅当返回值为类类型时,重写的方法才可以修改返回值类型,且必须是父类方法返回值的子类;要么就不修改,与父类返回值类型相同。那么,该如何理解呢?为什么要是父类返回值类型的子类?
提出问题:子类必须重写父类所有方法吗?
Java,子类不是必须重写父类所有方法的,分为以下两种情况:
父类方法为抽象方法时,子类必须重写(实现)所有父类的抽象方法;
父类方法为普通方法时,子类可以重写父类方法,也可以不重写。
举例如下:
abstract class A{
public void a(){
}
public abstract void b();
}
public class B extends A{
//必须重写b方法,a方法可以不重写
public void b(){
}
}
还是先看示例,详见下文。
包human中定义了三个类,Person类、Student类和TestMain类,其中Student类是Person类的子类。代码分别如下:
Person类的代码如下:
package human;
public class Person {
String name;
int age;
//test:重写
public Person overRide() {
Person per = new Person();
per.name = "liu";
return per;
}
}
Student类重写了父类的overRide()方法,代码如下:
package human;
public class Student extends Person {
String stuNumber;
int score;
//test:重写
public Student overRide() {
Student stu = new Student();
stu.name = "li";
return stu;
}
}
TestMain类的代码如下:
package human;
public class TestMain {
public static void main(String[] args) {
Student stu = new Student();
Person per = new Person();
per = stu.overRide();
System.out.println(per.name);
per = per.overRide();
System.out.println(per.name);
}
输出结果为:
li
li
有没有人跟我一样,第一反应输出应该为“li liu”呢,怎么两个都是“li”?
仔细分析一下,看下面的几张内存图就明白了。
第1、第2条语句分别创建一个子类对象和一个父类对象,其中,stu指向子类对象,per指向父类对象。如下面图1所示:
接着执行第3条语句:per = stu.overRide();;
stu先调用overRide(),方法体里创建了一个子类对象,并让临时变量stu指向该对象,其存储位置就是以C为首地址的内存块;
然后把该对象的变量name赋值为“li”;最后返回stu的值并赋给per,也就是说,虽然per是父类对象引用,但最后指向了overRide()里创建的子类对象,这里以蓝色箭头表示; 原先指向的以B为首地址的父类对象这时没有引用指向它,这里把红色箭头变为虚线表示。此时访问per的name,显然是“li”。内存结构见图2:
再接着要执行per = per.overRide();,调用overRide()方法;
由于子类重写了父类的overRide()方法,虽然per为父类对象引用,此时父类的该方法被覆盖,所以此时要调用子类的方法;执行过程同上,per不再指向以C为首地址的子类对象,改为指向新创建的子类对象,以D为首地址,如图3所示。
同上面一样的道理,此时访问per的name仍然为“li”,因为父类的overRide()两次压根都没有被调用到。
修改一下TestMain,如下所示:
package human;
public class TestMain {
public static void main(String[] args) {
Student stu = new Student();
Person per = new Person();
Person per2 = per;
// per = stu.overRide();
System.out.println(per.name);
per = per.overRide();
System.out.println(per.name);
per2 = per2.overRide();
//
System.out.println(per2.name);
//
}
此时定义了一个父类对象引用per2,并让它与per指向同一个对象;最后两行,由per2调用overRide()方法,很显然要调用父类的方法,所以方法体中创建的也是父类的对象,再把结果返回给per2,此时per2指向新创建的父类对象,该父类对象的name就为“liu”了。
说了这么多,貌似还没解决开头的问题,为什么是父类返回值类型的子类?为方便说明,记父类的返回值类型为A。
我的理解是,这是为了向上转型;既然子类重写了父类的方法,有时候就需要用父类对象引用来调用子类重写的方法,在上面例子的情况下,也就是说要把A的子类对象引用赋给A的对象引用,如果此时返回值类型不是A类或A的子类,其他类的对象引用是不能赋给A的对象引用的,这样就会出错;所以说,子类重写的方法,如果返回值为类类型,其返回值类型必须与父类返回值类型相同或为父类返回值类型的子类。
不知道有没有说清楚。
PS:例子选得不是特别好,如果返回值类型是与Person和Student不相干的类,可能更好理解,不然容易把返回值的类与方法所属的类混淆。
总结
Java中的静态内部类详解及代码示例
Java源码解析之object类
Java AtomicInteger类的使用方法详解
如有不足之处,欢迎留言指出。
来源:http://www.cnblogs.com/chanchan/p/7796472.html


猜你喜欢
- 这个小游戏是我和我姐们儿的JAVA课程设计,也是我做的第一个JAVA项目,适合初学者,希望能帮到那些被JAVA课设所困扰的孩纸们~~~一、该
- 一.需求使用JAVA实现单链表,使用单链表检测字符串是否是回文串二.需求分析回文串最重要的就是对称,那么最重要的问题就是找到那个中心,用快指
- System.Collections.ArrayList类是一个特殊的数组。通过添加和删除元素,就可以动态改变数组的长度。一.优点1。支持自
- 使用python和java实现数独游戏,有比较才有收获哦。1、Python版#--coding:utf-8--import ra
- 一. 假设需求场景在我们开发的过程中,经常出现两个对象存在一对多或多对一的关系。如何在程序在表明这两个对象的关系,以及如何利用这种关系优雅地
- 本文实例为大家分享了OpenGL绘制三次Bezier曲线的具体代码,供大家参考,具体内容如下计算公式:运行结果:代码如下:#include&
- 本文实例讲述了Java基于动态规划法实现求最长公共子序列及最长公共子字符串。分享给大家供大家参考,具体如下:动态规划法经常会遇到复杂问题不能
- 关于滑动冲突在Android开发中,如果是一些简单的布局,都很容易搞定,但是一旦涉及到复杂的页面,特别是为了兼容小屏手机而使用了Scroll
- 1、什么是Spring MVC?Spring MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用
- 前言最近开发中用到许多对话框,之前都是在外面的代码中创建AlertDialog并设置自定义布局实现常见的对话框,诸如更新提示等含有取消和删除
- 一、前言使用动态配置的原因: properties 和 yaml 是写到项目中的,好多时候有些配置需要修改,每次修改就要重新启动项目,不仅增
- 1、不知道为啥process.StartInfo.Arguments = "/c" + "start D:/T
- 这篇文章主要介绍了JAVA基于SnakeYAML实现解析与序列化YAML,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- 本文以实例描述了C#实现让窗体永远在窗体最前面显示的方法,具体步骤如下:1、新建一个窗体程序,添加一个Timer以及设置它可用并绑定事件。2
- 使用方法 首先在Github或者Gitee上面新建一个仓库复制仓库的链接用idea在本地新建一个demo项目点击菜单栏的VCS,按
- 目前在公司做一个小东西,里面用到了 FFmpeg 简单处理音视频,感觉功能特别强大,在做之前我写了一个小例子,现在记录一下分享给大家,希望大
- 最近在鼓捣spring -boot ,真好用,学习到jpa.通过生成Entity 文件,能够快速的生成数据库,并且使用JpaReposito
- C#编写winform程序时,用到的,格式强转,存储到数据库,数据库连接那块就不写了希望对大家有帮助,欢迎评论互相分享技术!//日期格式强制
- 本文实例讲述了Java实现将png格式图片转换成jpg格式图片的方法。分享给大家供大家参考,具体如下:import java.awt.Col
- clone()和Cloneable接口clone顾名思义就是克隆,即,复制一个相等的对象,但是不同的引用地址。我们知道拿到一个对象的地址,只