菜鸡的Java笔记 第二十 - java 方法的覆写
1.方法的覆写
当子类定义了与父类中的完全一样的方法时(方法名称,参数类型以及个数,返回值类型)这样的操作就称为方法的覆写
范例:观察方法的覆写
class A{
public void print(){
System.out.println("******************");
}
}
class B extendsa A{
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
b.print();
}
}
/*
结果:
******************
*/
此时B是A的子类,并且B类中没有定义任何的方法。此时B类将直接继承A类中的println()方法执行
范例:发生覆写
class A{
public void print(){
System.out.println("******************");
}
}
class B extendsa A{
public void print(){ // 方法名称一样
System.out.println("!!!!!!!!!!!!!!!!!!");
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
b.print();
}
}
/*
结果:
!!!!!!!!!!!!!!!!!!
*/
...
class A{
public void print(){
System.out.println("******************");
}
}
class B extendsa A{
public void print(){ // 与父类的方法完全一样
System.out.println("!!!!!!!!!!!!!!!!!!");
}
}
class C extendsa A{
public void print(){
System.out.println("¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥");
}
public class inherit{
public static void main(String args[]){
C c = new C();
c.print();
}
}
/*
结果:
¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
*/
(主要是看 new 谁)
此时的程序之中使用了B类进行对象的实例化操作,并且在B类中已经明确的覆写了A类中的print()方法
那么最终所调用的一定就是被覆写过的方法
范例:分析方法覆写的含义
class Person{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public String getlnfo(){
return "姓名:"+this.name
+",年龄:"+this.age;
}
}
class Student extends Person{ // Student 是Person 的子类
private String school; // 子类自己扩充的属性
public void setSchool(String school){
this.school = school;
}
public String getSchool(){
return this.school;
}
}
public class inherit{
public static void main(String args[]){
Student stu = new Student();// 实例化子类对象
stu.setName("少爷");//通过Person类继承而来
stu.setAge(20);//通过Person类继承而来
stu.setSchool("清华");//子类自己扩充的属性
System.out.println(stu.getlnfo());
}
}
/*
结果: (问题:少了School 这个值)
姓名:少爷,年龄:20
*/
******************************************
class Person{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public String getlnfo(){
return "姓名:"+this.name
+",年龄:"+this.age;
}
}
class Student extends Person{ // Student 是Person 的子类
private String school; // 子类自己扩充的属性
public void setSchool(String school){
this.school = school;
}
public String getSchool(){
return this.school;
}
public String getlnfo(){ // 保留方法名称,但是有需要对功能进行扩充
return super.getlnfo()
+"学校:"+this.school;
// return "姓名:"+super.getName()
+",年龄:"+super.getAge()
+"学校:"+this.school;
}
public class inherit{
public static void main(String args[]){
Student stu = new Student();// 实例化子类对象
stu.setName("少爷");//通过Person类继承而来
stu.setAge(20);//通过Person类继承而来
stu.setSchool("清华");//子类自己扩充的属性
System.out.println(stu.getlnfo());
}
}
实质上所谓的方法覆写原因:
父类中定义的方法名称是其他程序所认可的名称,属于使用的习惯
但是子类在使用的过程之中,发现原始的方法不能够支持自己的操作,而且又需要保留猪方法名称,这样才出现了覆写的概念
并且通过以上的分析可以发现一点:
this.方法():会先找本类中是否有指定的方法,如果本类没有则使用父类继承而来的方法
super.方法():不查找本类的方法,而直接找父类的方法
但是覆写本身也是有严格要求的:被覆写的方法不能够拥有比父类更为严格的访问控制权限。
对于访问的控制权限严格来讲一共有四个,已经学习过三个:private<default(friend)<public
按照以上的思路,如果说现在父类中的方法使用了public访问权限声明,那么子类只能够使用public 而如果父类使用了default访问权限声明,那么子类可以使用public或default
范例:错误的覆写
class A{
public void print(){
System.out.println("******************");
}
}
class B extendsa A{
void print(){ // 此时的方法访问权限严格
System.out.println("!!!!!!!!!!!!!!!!!!");
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
b.print();
}
}
/*
结果:出错
*/
但是此时又会出现这样一种情况,如果父类中的方法使用了private呢?那么子类覆写方法时如果使用了default也属于权限扩大这样可以覆写吗?
范例:正常覆写
class A{
public void fun(){
this.print();
}
public void print(){
System.out.println("******************");
}
}
class B extendsa A{
public void print(){
System.out.println("!!!!!!!!!!!!!!!!!!");
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
b.fun();
}
}
/*
结果:
!!!!!!!!!!!!!!!!!!
*/
下面将父类中的println()方法权限修改为private
class A{
public void fun(){
this.print();
}
private void print(){
System.out.println("******************");
}
}
class B extendsa A{
public void print(){
System.out.println("!!!!!!!!!!!!!!!!!!");
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
b.fun();
}
}
/*
结果:
******************
*/
从权限的角度来看此时应该符合覆写的要求
通过结果可以发现,此时子类并没有进行方法的覆写所以就可以得出结论:
父类中private声明的方法不能够被子类所覆写,而且最重要的是这样的操作几乎没有意义
在实际之中对于方法的定义,95%的情况下都只会使用public声明
在进行方法覆写之后都会存在有一个就近取用的关系,如果面对本类方法自己调用自己的情况,因为默认情况下调用本类方法时都会采用“this.方法()” 的形式处理
而在使用this调用结构的时候,会首先找到本类如果本类找不到的操作再去查找父类
为了可以不查找本类而直接找到父类,建议使用“ super.方法() ” 的形式调用
以后为了表示明确,强烈建议:子类访问父类方法前都是 super
面试题:请解释Overloading与Override的区别?在进行Overloading的时候能否返改变回值类型
| 区别 | 方法重载 | 方法覆写 |
| 单词 | Overloading | Override |
| 范围 | 发生在一个类中 | 发生在继承关系之中 |
| 定义 | 方法名称相同,参数的类型以及个数不同 | 方法名称相同,参数的类型以及个数,返回值全部相同 |
| 权限 | 没有权限要求 | 被覆写的方法不能拥有比父类更为严格的访问控制权限 |
在进行方法重载的时候可以使用不同的返回值类型,但是从设计的标准来讲不建议使用
2.属性的覆盖
当子类定义了与父类属性名称相同的属性时,就称为属性的覆盖
范例:观察属性的覆盖
class A{
String info = "mysterious";
}
class B extendsa A{
int info = 100; // 名称相同
public void print(){
System.out.println(this,info);
System.out.println(super.info);
}
}
public class inherit{
public static void main(String args[]){
B b= new B();
b.print();
}
}
/*
结果:
100
mysterious
*/
从实际开发的标准要求来讲,类中的属性必须使用private封装,那么一旦使用了private封装属性覆盖没有意义了
面试题:请解释this与super的区别?
| 区别 | this | super |
| 概念 | 表示调用本类属性(this.属性),本类方法(this.方法,this()) | 调用父类属性(super.属性),父类方法(super.方法(),super()) |
| 构造要求 | 调用构造方法是必须放在构造方法的首行,所以this()与super()不能够同时出现,但是子类永远会去调用父类中的构造方法 | 调用构造方法是必须放在构造方法的首行,所以this()与super()不能够同时出现,但是子类永远会去调用父类中的构造方法 |
| 特殊要求 | 表示当前对象 |
使用this实际上会先从本类开始查找所需要的内容,如果没有去查询父类,而如果使用的是super则表示不查询本类直接查找父类的定义
总结
1.所有类中的属性都必须使用private定义,这样一来覆盖属性就没有任何意义了
2.方法的覆写调用特点:
看实例化的是那个子类的对象(new 出现在哪里或者说是new哪个类)
观察调用的方法是否已经被该子类覆写,如果覆写则调用被覆写的方法,如果没有覆写则调用从父类继承而来的方法
菜鸡的Java笔记 第二十 - java 方法的覆写的更多相关文章
- 菜鸡的Java笔记 第二十三 - java 抽象类的概念
abstractClass 抽象类的概念 1.抽象类的基本定义 2.抽象类的使用原则 不会抽象类与接口,java = 没学 ...
- 菜鸡的Java笔记 第二十七 - java 链表基本概念
链表基本概念 1.链表的基本形式 2.单向链表的完整实现 认识链表 链表= 可变长的对象数组,属于动态对象数组的范畴 链表 ...
- 菜鸡的Java笔记 第二十八 - java 包的定义
包的主要作用以及定义 包的导入操作 系统常见的开发包 jar 程序命令 包的定义 在任何的操作系统之中都有一个统一的共识:同一个目录下不能够存在有相同的文 ...
- 菜鸡的Java笔记 第二十六 - java 内部类
/* innerClass 从实际的开发来看,真正写到内部类的时候是在很久以后了,短期内如果是自己编写代码,几乎是见不到内部类出现的 讲解它的目的第一个是为了解释概念 ...
- 菜鸡的Java笔记 第二十四 - java 接口的基本定义
1.接口的基本定义以及使用形式 2.与接口有关的设计模式的初步认识 3.接口与抽象类的区别 接口与抽象类相比,接口的使用几率是最高的,所有的 ...
- 菜鸡的Java笔记 第二十二 - java 对象多态性
本次只是围绕着多态性的概念来进行讲解,但是所讲解的代码与实际的开发几乎没有关系,而且多态一定是在继承性的基础上才可以操作的, 而本次将使用类继承的关系来描述多态的性质,实际的开发中不会出 ...
- 菜鸡的Java笔记 第二十五 wrapperClass 包装类
wrapperClass 包装类 1.包装类的特点 2.装箱与拆箱操作 3.数据转型处理 内容 Object 类可以接收 ...
- 菜鸡的Java笔记 第二十九 - java 单例设计模式
SingleCase 单例设计模式 1.单例设计模式的特点 2.多例设计模式的特点 内容 单例设计模式 现在如果说有这么一个程序类 class S ...
- 菜鸡的Java笔记 第十 - java 类与对象
(局部变量需要初始化,全局变量不初始化系统也会帮忙初始化而局部变量系统不会帮忙初始化)>>> 2.1 类与对象基本概念 在现实生活之中,类指的就是具备某一共性的群 ...
随机推荐
- 【.NET 与树莓派】气压传感器——BMP180
BMP180 是一款数字气压计传感器,实际可读出温度和气压值.此模块使用 IIC(i2c)协议.模块体积很小,比老周的大拇指指甲还小:也很便宜,一般是长这样的.螺丝孔只开一个,也有开两个孔的. 这货基 ...
- MySQL学习总结:提问式回顾 undo log 相关知识
原文链接:MySQL学习总结:提问式回顾 undo log 相关知识 1.redo 日志支持恢复重做,那么如果是回滚事务中的操作呢,也会有什么日志支持么? 也回滚已有操作,那么就是想撤销,对应的有撤销 ...
- 踩坑系列《二》NewProxyResultSet.isClosed()Z is abstract 报错踩坑
在运行测试类的时候莫名其妙的报了个 NewProxyResultSet.isClosed()Z is abstract 这个错误,之前出现过这个错误,以为是版本出现了问题 就将版本 0.9.1.2 改 ...
- Fortran学习笔记:01 基本格式与变量声明
Fortran学习笔记目录 01 基本格式与变量声明 格式 固定格式(Fixed Format):Fortran77 程序需要满足一种特定的格式要求,具体形式参考教材 自由格式(Free Format ...
- 密码学系列之:加密货币中的scrypt算法
目录 简介 scrypt算法 scrypt算法详解 scrypt的使用 简介 为了抵御密码破解,科学家们想出了很多种方法,比如对密码进行混淆加盐操作,对密码进行模式变换和组合.但是这些算法逐渐被一些特 ...
- SphereEx 获数百万美元天使融资,接力 ShardingSphere 开启 Database Plus 新篇章
5月14日,数据前沿技术领域初创公司 SphereEx 获得来自红杉中国种子基金.初心资本的数百万美元天使轮融资. SphereEx是一家致力于构建新型分布式数据基础设施的公司,秉承开源.共享.生态. ...
- SpringBoot使用注解进行分页
分页使用可以说非常普遍了,有时候会需要非常灵活的方式去开启或关闭分页,尝试使用一下注解的方式来进行分页. 依赖安装 需要使用的依赖: Mybatis-Plus PageHelper SpringBoo ...
- JVM详解(三)——运行时数据区
一.概述 1.介绍 类比一下:红框就好比内存的运行时数据区,在各自不同的位置放了不同的东西.而厨师就好比执行引擎. 内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的 ...
- Linux服务器装Anaconda&TensorFlow
远程Linux服务器装Anaconda&指定版本TensorFlow 说明: 由于疫情影响,原先使用的服务器已断电,故重选了一台服务器对环境重选进行搭建,正好补上这篇博文. 01 下载Anac ...
- Beta实际开发与初始计划的比较
零.说明 本篇博客为Beta阶段开始十天后,实际开发工作与初始计划的比较 截止至本篇博客发布为止,团队所有成员已完成计网考试,将在本周日进行充分的接口测试 一.比较 1.与初始计划对比 初始计划 实际 ...