Java_继承和多态

文章目录

  • 前言
  • 继承
    • 继承语法
    • 继承总结
    • super指定访问父级
    • 子类构造方法
    • super和this
    • 再谈初始化(执行顺序)
    • protected 关键字
    • 继承方式
    • final 关键字
    • 继承与组合
  • 多态
    • 动态绑定与静态绑定
    • 多态实现条件
    • 重写

前言

适合复习看

继承

继承语法

在这里插入图片描述

修饰符 class 子类 extends 父类 {
// ...
}

子类会将父类中的成员变量或者成员方法继承到子类中了

子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了

继承总结

在子类方法中 或者 通过子类对象访问成员时:

  1. 如果访问的成员变量子类中有,优先访问自己的成员变量。
  1. 如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
  1. 如果访问的成员变量与父类中成员变量同名,则优先访问自己的

成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找


子类中访问父类的成员方法时:

  1. 通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
  1. 通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法视传递的参数选择合适的方法访问,如果没有则报错

super指定访问父级

Java提供了super关键字,该关键字主要作用:在子类方法中访问父类的成员。

在这里插入图片描述

注意

  1. 只能在非静态方法中使用
  2. 在子类方法中,访问父类的成员变量和方法

子类构造方法

父子父子,先有父再有子,即:子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法

在子类构造方法中,并没有写任何关于基类构造的代码,但是在构造子类对象时,先执行基类的构造方法,然后执行子类的构造方法,因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整。

注意:

  1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构
    造方法
  2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的
    父类构造方法调用,否则编译失败。
  3. 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。
  4. super(…)只能在子类构造方法中出现一次,并且不能和this同时出现(构造方法 this() 和 super() 都必须在第一行,所以不能同时出现)

super和this

【相同点】

  1. 都是Java中的关键字
  2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
  3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

【不同点】

  1. this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成
    员的引用
  2. 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
  3. 在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造
    方法中出现
  4. 构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有

再谈初始化(执行顺序)

在这里插入图片描述

1、父类静态代码块优先于子类静态代码块执行,且是最早执行
2、父类实例代码块和父类构造方法紧接着执行
3、子类的实例代码块和子类构造方法紧接着再执行
4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

使用static关键字定义的代码块,一般用于初始化静态成员属性;静态代码块不管生成多少个对象,其只会执行一次,且是最先执行的;然后就地初始化普通(实例)代码块初始化看书写的先后顺序,写在前面的先执行;然后才是构造方法初始化。

protected 关键字

在这里插入图片描述

子类 就是 基类(父类)的派生类(子类)

protected修饰的 可以调用 在不同包中的,继承该包的类的子类


注意:父类中private成员变量虽然在子类中不能直接访问,但是也继承到子类中了

什么时候下用哪一种呢?
我们希望类要尽量做到 “封装”, 即隐藏内部实现细节, 只暴露出 必要 的信息给类的调用者.
因此我们在使用的时候应该尽可能的使用 比较严格 的访问权限. 例如如果一个方法能用 private, 就尽量不要用 public.

另外, 还有一种 简单粗暴 的做法: 将所有的字段设为 private, 将所有的方法设为 public. 不过这种方式属于是
对访问权限的滥用, 还是更希望同学们能写代码的时候认真思考, 该类提供的字段方法到底给 “谁” 使用(是类内部自己用, 还是类的调用者使用, 还是子类使用)

继承方式

Java中只支持以下几种继承方式:
在这里插入图片描述

注意:Java中不支持多继承。

时刻牢记, 我们写的类是现实事物的抽象. 而我们真正在公司中所遇到的项目往往业务比较复杂, 可能会涉及到一系列复杂的概念, 都需要我们使用代码来表示, 所以我们真实项目中所写的类也会有很多. 类之间的关系也会更加复杂.

但是即使如此, 我们并不希望类之间的继承层次太复杂. 一般我们不希望出现超过三层的继承关系. 如果继承层次太多, 就需要考虑对代码进行重构了.
如果想从语法上进行限制继承, 就可以使用 final 关键字

final 关键字

final关键可以用来修饰变量、成员方法以及类。

  1. 修饰变量或字段,表示常量(即不能修改)
final int a = 10;
a = 20; // 编译出错
  1. 修饰类:表示此类不能被继承
final public class Animal {
...
}
public class Cat extends Animal {
...
} 
// 编译出错
//Error:(3, 27) java: 无法从最终com.bit.Animal进行继承

我们平时是用的 String 字符串类, 就是用 final 修饰的, 不能被继承

  1. 修饰方法:表示该方法不能被重写

继承与组合

和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法
(诸如 extends 这样的关键字), 仅仅是将一个类的实例作为另外一个类的字段。

继承表示对象之间是is-a的关系,比如:狗是动物,猫是动物

组合表示对象之间是has-a的关系,比如:汽车和其轮胎、发动机、方向盘、车载系统等的关系就应该是组合,因为汽车是有这些部件组成的

class Student2 {

}
class Teacher {

}

class School {

    public Student2[] student2s = new Student2[10];
    public Teacher[] teachers = new Teacher[5];
    //不用继承就能使用"父类"

}

注意组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据应用场景来选择,一般建议:能用组合尽量用组合

多态

动态绑定与静态绑定

多态的本质就是利用动态绑定,不同对象执行的效果也不一样

动态绑定
(假设,有一父类和一子类,里面都有除了内容外完全相同的eat方法)
创建父类类型的引用A,让A指向子类(new子类),然后用A调用eat方法时
编译的时候 认为 还是调用了父类的eat方法, 不过运行的时候 绑定到了子类当中

静态绑定
编译的时候,已经确定了调用那个方法了
(例如,类中有不带参数的构造方法A和带参数的构造方法B,调用构造方法时,带参数那就是执行构造方法B,不带参数则执行构造方法A)

多态实现条件

在java中要实现多态,必须要满足如下几个条件,缺一不可:

  1. 必须在继承体系下
  2. 子类必须要对父类中方法进行重写
  3. 通过父类的引用调用重写的方法

多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法

父类:

class Animal {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
    public void eat() {
        System.out.println("eat");
    }
}

两个子类:

class Cat extends Animal {
    Cat(String name) {
        super.setName(name);
    }
    @Override//对父类的eat进行重写
    public void eat() {
        System.out.println(super.getName() + "吃猫粮");
    }
}
class Dog extends Animal {
    Dog(String name) {
        super.setName(name);
    }
    @Override//对父类的eat进行重写
    public void eat() {
        System.out.println(super.getName() + "吃狗粮");
    }
}

测试:

class test {
    public static void main(String[] args) {
        Animal animal = new Cat("猫猫");//向上转型,把子类传给父类的类型
        animal.eat();

        animal = new Dog("狗子");
        animal.eat();
        //打印为:
        //猫猫吃猫粮
        //狗子吃狗粮
    }
}

重写

重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法

方法重写规则:

  1. 子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致
  2. 被重写的方法返回值类型可以不同,但是(返回类型)必须是具有父子关系的
  3. 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方
    法就不能声明为 protected
  4. 父类被static、private修饰的方法构造方法不能被重写
  5. 重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (eat比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法
    构成重写

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

配置cuda和cudnn出现 libcudnn.so.8 is not a symbolic link问题

cuda版本为11.2 问题如图所示: 解决办法: sudo ln -sf /usr/local/cuda-11.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8.1.1 /usr/local/cuda-11.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8 sudo ln -sf /usr/local/cuda-11.2/targ…

Mac安装配置Tomcat,以及使用(详解)

目录 一、Tomcat下载: 1、左栏选择Tomcat版本 2、点击下载即可,任选其一 ​编辑3、下载好的文件夹放到用户名下即可(之前已经下载过,这里以Tomcat 8.5.88为演示),这里提供8.5.88的安装包: 二…

毅速丨金属3D打印零件品质受哪些因素影响

金属3D打印的零件品质受到多个因素的影响,包括设备、材料、工艺、后处理等。不同厂商的品质差别大致由以下几个方面造成。 一、设备性能差异: 不同厂商的金属3D打印设备可能存在性能上的差异,包括激光功率、扫描速度、打印精度、稳定性等。这…

istio流量管理

流量管理 目录 文章目录 流量管理目录流量管理概述请求路由1.路由到版本1🚩 实战:路由到版本1-2023.11.11(测试成功) 2.基于用户身份的路由🚩 实战:基于用户身份的路由-2023.11.11(测试成功) 关于我最后 流量管理概述 上面我们了…

跨镜头目标融合__追踪之目标重识别研究(跨镜头目标追踪)

文章目录 标题:跨镜头目标融合;目标重识别;跨镜头目标追踪; 1 目的:2 实现方法/策略:2.1 目标类型位置匹配(或考虑结合目标轨迹)2.2 目标重识别2.3 目标类型位置匹配(轨迹)目标重识别…

LeetCode【701】二叉搜索数的插入操作

题目: 思路: https://zhuanlan.zhihu.com/p/272781596 代码: class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {return process(root,val); }//递归public TreeNode process(TreeNode root,int val){//base ca…

Hls学习(一)

1:CPU、DSP、GPU都算软件可编程的硬件 2:dsp在递归方面有所减弱,在递归方面有所增强,比如递归啊等,GPU可以同时处理多个进程,对于大块数据,流处理比较适用 3:为了提高运算量处理更多…

可视化 | 3D文字球状标签云

文章目录 📚改编点📚final 改编自echarts 3d词云(指向滑动、拖动、缩放、点击、自转 ) 📚改编点 背景透明:background:rgb(0,0,0,0);不用链接,用span,重点span标class"star&q…

文心耀乌镇,“大模型之光”展现了什么?

“乌镇的小桥流水,能照见全球科技的风起云涌。” 多年以来,伴随着中国科技的腾飞,以及世界互联网大会乌镇峰会的连续成功举办,这句话已经成为全球科技产业的共识。乌镇是科技与互联网的风向标、晴雨表,也是无数新故事开…

【ATTCK】MITRE Caldera 简介

一、什么是Caldera caldera是一个基于MITRE ATT&CK™构建的网络安全框架。其目标是创建一种工具,通过提供自动化安全评估来增强网络从业者的能力,从而节省用户的时间、金钱和精力。为此,需要几个关键组件才能使 Caldera 成为行业领先的平…

外接式网络隔离变压器/网络隔离滤波器/网口变压器/脉冲变压器/网络隔离变压器模块

Hqst华强盛(石门盈盛)电子导读:外接式网络隔离变压器/网络隔离滤波器/网口变压器/脉冲变压器/网络隔离变压器模块,后统称网络隔离变压器,它是一种安装在电路外部的隔离变压器,主要用于隔离网络中的干扰信号…

巨好用又实用的18款3dMax插件!

3dMax是一款功能强大的 3D 软件,具有建模、动画、粒子动力学等许多强大功能。但并不是每个人都能有效地利用max的每一个功能,例如,很多人发现3dmax粒子流太难使用,3ds max蒙皮工具也是如此。 这让我们一些专业的开发公司或个人和…

跨域:利用iframe实现跨域DOM互访的四种方式

注:跨域的知识点详见:跨域相关知识点 目录 实验验证环境配置: 1、利用document.domain降域 方法1: 方法2: 2、利用location.hash 3、利用window.name 4、利用postMessage(最推荐) 使用postmessage实现跨域访问…

视频剪辑助手:轻松实现视频随机分割并提取音频保存

随着社交媒体和视频平台的日益普及,视频制作和分享已成为人们日常生活的一部分。无论是分享个人生活,还是展示才艺,或是推广产品,视频都是一个非常有效的工具。但是,视频制作往往涉及到大量的视频剪辑工作,…

卡码网语言基础课 | 11. 句子缩写

目录 一、 字符串大小的比较 二、 ASCII码值 三、 基本框架代码 四、 解题思路 4.1 首字母问题 4.2 判定小写字母 4.3 小写字母转换为大写字母 五、空格判断 六、 代码模块化 6.1 满足的条件 6.2 代码完善 七、 题目解答 7.1 原始代码 7.2 改进代码 八、 拓展与…

Redis五种数据类型及命令操作(一)

🎈个人公众号:🎈 :✨✨✨ 可为编程✨ 🍟🍟 🔑个人信条:🔑 知足知不足 有为有不为 为与不为皆为可为🌵 🍉本篇简介:🍉 本篇记录Redis五种数据类型及命令操作,如…

[BJDCTF2020]Easy MD5 1

题目环境: 尝试了SQL注入、命令执行等都不行 点击提交并burp进行抓包Repeater进行重放这里看到了内置的SQL语句select * from admin where passwordmd5($pass,true) 发现传进去的值会进行md5加密 这里看了大佬们的解释 ffifdyop绕过,绕过原理是&#xff…

计算机网络期末复习-Part3

1、rdt1.0,rdt2.0,rdt3.0的底层信道模型 RDT 1.0: 完全可靠的底层信道,没有比特差错,也没有分组丢失。 RDT 2.0: 具有比特差错的底层信道,有比特差错,但没有分组丢失。 RDT 3.0: 具有差错和丢包的底层信道…

聊聊性能测试的左移右移

前面的文章中,分享过我对于测试左移右移的一些思考和实践方法。有同学在后台留言问我:常规的性能测试一般都是在测试阶段集成测试时候才开始介入,很容易测试时间不够,可不可以借鉴测试左移右移的思路,更早的介入和发现…

实战Leetcode(三)

Practice makes perfect! 实战一: 带环问题其实我们小学时就接触过,就比如在操场上比赛跑步的追击问题,这里也是一样,如果我们定义两个指针,一个快指针,一个慢指针,快指针走的快&…