体会多态的好

news2025/8/3 0:09:20

目录

 继承和组合:

 区别和联系

1.安全性角度(封装性)

2.灵活性角度(牵一发动全身)

 多态:

一.怎样实现多态

1.完成向上转型

直接赋值:​​​​​​​

方法传参

方法的返回值

2.完成方法重写:

3.通过父类引用指向子类对象(重写的方法)

 动态绑定

父类引用指向子类对象:

二.什么是多态:

三.多态思想的运用(画图形)

四.多态的好处:

补充内容:

1.总结重写和重载区别:

2. 向下转型

  • 不安全的:
  • 引入instance of 

---

 前言
这些内容是对javase基础部分的复习

---

 继承和组合:


1.关系上说:
继承 is a
组合 has a
2.用法上说:
组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据应用场景来选择,一般建议:能用组合尽量用组合。

>类似于造车,一个车可以由轮子,灯.....构成用组合写代码如下

组合的代码:

```java
//演示组合
class Tire{
    private int size;

    public void run(){
        System.out.println("轮胎转动");
    }

}
class Light{
    public void bright(){
        System.out.println("灯亮");
    }

}
public class Vehicle {
    private Tire tire;
    private Light light;
    public Vehicle(Tire tire,Light light){
        this.tire=tire;
        this.light=light;
    }
    public void operation(){
        tire.run();
        light.bright();
    }
    public static void main(String[] args) {
        Tire tire=new Tire();
        Light light=new Light();
        Vehicle vehicle=new Vehicle(tire,light);
        vehicle.operation();
    }

}


 区别和联系


1.安全性角度(封装性)


组合是拼装在一起内部实现细节是不可见的,具有更好的封装性(黑盒)
在继承结构中,父类的内部细节对于子类是可见的。所以我们通常也可以说通过继承的代码复用是一种白盒式代码复用。(如果基类的实现发生改变,那么派生类的实现也将随之改变。这样就导致了子类行为的不可预知性;)

比如:类的方法被其他类用到,万一其他类重写了该方法,这个方法对后续会有影响(所有用到)


2.灵活性角度(牵一发动全身)


继承,在写代码的时候就要指名具体继承哪个类,所以,在编译期就确定了关系。(从基类继承来的实现是无法在运行期动态改变的,因此降低了应用的灵活性。)
比如:回调(每次继承一次,回调一遍其中的方法和属性)

组合,在写代码的时候可以采用面向接口编程。所以,类的组合关系一般在运行期确定


 多态

一.怎样实现多态


1.完成向上转型

注意三点

直接赋值:

直接把子类对象赋给父类

Animal animal=new Bird("鹦鹉",2);

animal.eat()

此时父类引用只能访问自己的方法,要想访问子类特有方法的需要向下转型

方法传参

方法的返回值

2.完成方法重写:

注意6点

 animal.eat();

 

 调用的是子类的eat()

上述过程其实就是一次方法重写


满足方法重写的条件:
1.方法名相同,
2.参数列表相同【个数,类型,顺序】
3.返回值相同(或者子类的返回值和父类构成父子类关系(协变类型))

这是子类

这是父类:

public Animal eat() {
        System.out.println(name + "会干饭");
        return new Animal("动物",18);
    }

由于子类的返回值和父类构成父子类关系,运行结果还是子类的eat

4.static修饰方法不能被重写


5.private修饰方法不能被重写(private只能在当前类使用)


6.子类的访问修饰符,需要大于等于父类的访问修饰符


对父类方法重写

3.通过父类引用指向子类对象(重写的方法)

发生了动态的绑定

 动态绑定

又叫运行时绑定,子类和父类都有这个方法

编译的时候,还是调用父类自己的,但是在运行的时候,程序发生了动态绑定---子类自己的

这是编译时候的样子:

 运行时候,编译器悄悄将animal.eat方法地址改成0x56

父类引用指向子类对象:

//        Bird bird=new Bird("鹦鹉",2);
//        Animal animal=bird;

Animal animal=new Bird("鹦鹉",2);

animal.eat()

此时父类引用只能访问自己的方法,要想访问子类特有方法的需要向下转型

二.什么是多态:

public static void function(Animal animal) {
    animal.eat();//调用者不关心谁吃
}

public static void main(String[] args) {
    function(new Bird("鹦鹉",2));
    function(new Dog("狗子",1));
}

父类引用引用了子类对象,通过父类引用,调用这个重写的方法,此时发生了动态绑定,此时父类引用就这一个,但是我引用的对象不一样,通过调用同一个方法,我们发现,此时所表现的形式是不一样的,把这样的现象叫做多态

三.多态思想的运用(画图形)

package 多态;
class Shape{
    public void draw(){
        System.out.println("画图形");
    }
}
class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("长方形");
    }
}
class Cycle extends Shape{
    @Override
    public void draw() {
        System.out.println("圆形");
    }
}
class Triangle extends Shape{
    @Override
    public void draw() {
        System.out.println("△");
    }
}
public class Test2 {
    public static void drawMAP(Shape shape){
        shape.draw();
    }
    public static void main(String[] args) {
       Rect rect=new Rect();
       Cycle cycle=new Cycle();
       Triangle triangle=new Triangle();
       drawMAP(rect);
       drawMAP(cycle);
       drawMAP(triangle);
    }
}

假设现在要画的图形在shape数组中

    public static void main(String[] args) {
        Rect rect=new Rect();
        Cycle cycle=new Cycle();
        Triangle triangle=new Triangle();
        Shape[]shapes={rect,cycle,rect,cycle,rect,triangle};
        for (Shape shape:shapes) {
            //当前shape引用对象重写draw方法就调用,没有就调用自己的(已经向上转型和动态绑定了)
            shape.draw();
        }
    }

如果不使用多态

四.多态的好处:

1.降低了圈复杂度(减少条件循环语句出现的个数)

2.扩展能力强

补充内容:

总结重写和重载区别:

方法重载是静态绑定,在编译的时候,在编译时根据实参类型就知道具体的方法

方法重写是动态绑定,在运行的时候,确定调用哪个方法,

 

 重写就是重写再搭一个弓箭,重载是在原来基础上加功能,

 即:方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现

 向下转型

不安全的:

编译不报错: 

   //说明向下转型不安全
    public static void main(String[] args) {
        Animal animal = new Dog("狗子", 16);
        Bird bird = (Bird) animal;
        bird.fly();
    }


    public static void main1(String[] args) {
        Animal animal=new Bird("小鸟",2);
        Bird bird=(Bird)animal;//向下转型,父类类型给子类类型
        bird.fly();
    }

运行时,main显示:(狗子不是鸟)

 main1因为子类具有这个属性没事(鸟是动物)

修改代码:

引入instance of 

public static void main(String[] args) {
        Animal animal = new Dog("狗子", 16);
        if (animal instanceof Bird) {
            //不是所有动物都是鸟
            Bird bird = (Bird) animal;
            bird.fly();
        }
    }

狗子不是鸟,显然,没有输出,无法向下转型

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

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

相关文章

零基础数据科学学习 Python 的 4 个阶段

前言 如果你一直在自学 Python,那么你可能看过无数教程并遵循许多指南来获得这项技能,但是你怎么知道自己走在正确的道路上来掌握这项数据科学的基本技能? (文末送读者福利) Python 是一种实用的编程语言&#xff0c…

获取CSV文件,转成Excel格式的文件供用户从浏览器下载

前言 最近这十几天每天都很充实,刚完成了几个小需求;今天简单记录一下其中一个:从某系统获取csv文件,然后处理成可供用户在浏览器中下载的Excel文件; 这其中有解除到新的内容,也有利用项目已有的部分功能…

智慧图书馆解决方案-最新全套文件

智慧图书馆解决方案-最新全套文件一、建设背景二、思路架构三、建设方案四、获取 - 智慧图书馆全套最新解决方案合集一、建设背景 现下,传统图书馆已经难以适应时代的发展,图书盘点繁琐、管理模式落后、阅读时间和场地受限等问题,迫使传统图…

148. SAP UI5 表格数据如何导出成 Excel 文件(Table Export As Excel)

本教程前一步骤,我们在介绍 SAP UI5 SmartTable 时,提到了它的 Excel 导出功能。如果将 iseExportToExcel 设置为 true,就可以启用 Excel 导出功能,将 Table 控件显示的数据,导出成本地 Excel 文件。 我们仍然秉承本教程一贯从易到难的学习思路,先暂时不去碰 Smart Table…

30天消化MyBatis源码解析笔记,吊打面试官,offer接到手软

MyBatis 是一个优秀的 Java 持久化框架,SSM 框架组合(Spring SpringMVC Mybatis),依赖 MyBatis 搭建的项目更是数不胜数,在互联网公司的使用中,占据了大片江山,你在使用 MyBatis 吗&#xff1…

嵌入式开发:RTOS调试——处理计时问题

毫无疑问,当你开始在嵌入式开发中使用实时操作系统(RTOS)时,会有一个学习曲线。你将在更高的抽象层次上工作,使用或多或少的并行任务,而不仅仅是子例程,并且你需要考虑你的任务应该如何彼此共享数据和处理器时间。你需…

一个系统五个场景,vivo的IoT能否以“慢”取胜?

近年来物联网声浪喧嚣尘上,但其实从移动互联网到IoT只有一步之遥。原因在于手机可以很好的完成“控制中枢”的作用,以手机为核心在IoT领域“开枝散叶”是目前行业的主流选择,这也是小米、华为等手机巨头在IoT领域如鱼得水、产品众多的重要原因…

企业如何防备密码攻击

在身份安全周,了解密码在网络安全中的重要性很有必要,如果您不小心,密码很容易被泄露。ManageEngine ADSelfService Plus如何帮助强化密码并增强企业组织安全性的呢? 现在是 2022 年——密码在今天仍然适用吗? 技术…

Docker(九)—— Docker 网络

我们之前通过端口映射实现过外部主机对容器的访问, 那如果想要实现两个容器之间的通信怎么办?用已有的经验,是像图中蓝色的线那样走吗? 一、Docker0网络 我们运行一个容器,进入容器内部后发现容器也有自己的IP地址。 而…

磁盘占用高问题如何排查?三步教你搞定

作者简介:杨嘉力,OceanBase开源内核高级工程师。 通常情况下,数据库对磁盘的占用量会随着业务的接入时间和业务数据量大增而不断上升,导致磁盘空间不足,进而发生数据无法写入、数据库无法重启等问题。这时我们就需要排…

CENTOS上的网络安全工具(十三)搬到Docker上(1)?

鉴于在集群上构建安全工具的情况越来越频繁,并且现在一些安全工具也提供了Docker形式的部署,再停留在虚拟机yum的部署方式似乎已经不太合时宜了。所以在再一次碰到一个安全工具需要使用docker安装的时候,我们毅然(被逼&#xff09…

[附源码]SSM计算机毕业设计中小企业人事管理系统JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

[附源码]Python计算机毕业设计安庆师范大学校园互助平台

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

C语言学习记录(十二)之字符串和字符串函数

文章目录一、字符串和字符串I/O1.1 定义字符串1.1.1 字符串字面量(字符串常量)1.1.2 字符串数组和初始化1.1.3 数组和指针1.1.4 数组和指针的区别二、字符串输入2.1 分配空间2.2 gets()函数 (不建议使用)2.3 gets()的替代品2.3.1 fgets()函数(和fputs())2.3.2 gets_s()函数2.3.…

【推荐算法毕业设计源码】个性化学习推荐网站的设计及实现丨可定制

登录该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等学习内容。 目录 一、项目介绍: 二、文档学习资料: 三、模块截图: 四、开发技术与运行环境: 五、代码展示: 六、数据库表截图&#x…

UE4 GIS Cesium for Unreal插件的使用 教程

效果:(成都郫都区某区域的运行场景) 步骤: 1.到虚幻商城搜索 cesiuml,点击Cesium for Unreal 打开后可以看到目前支持的版本有4.26-4.27和5.0 将其安装到引擎 大概0.2G 2.下载完成后,打开4.26版本的虚幻编…

Study Git - Shell command with Git

前言 这一部分内容主要记录git使用时的重要命令&#xff0c;文章参考&#xff1a; MIT Missing classGit Pro Basic git help \<command>: get help for a git commandgit init: creates a new git repo, with data stored in the .git directorygit status: tells yo…

pytest学习和使用9-fixture中conftest.py如何使用?

9-fixture中conftest.py如何使用&#xff1f;1 引入2 conftest.py简介3 conftest.py特点4 实例4.1 conftest.py4.2 test_conftest1.py4.3 test_conftest2.py5 conftest.py优先级1 引入 之前学习使用fixture前置实现用例的登陆&#xff0c;当时在一个脚本中实现的&#xff1b;那…

基于PHP+MySQL学生创新作品展示系统的设计与实现

MySQL学生创新作品展示系统的基本功能包括用户注册登录,发布作品,查看作品和对评论评论以及在线留言等信息。 PHP本科学生创新作品展示系统是一个服务类型的网站,系统通过PHp&#xff1a;MySQL进行开发,分为前台和后台两部分,前台部分主要是让大学生查看和发布创新作品使用的。…

N3-PEG-MAL,Azdio-PEG-Maleimide,一种点击化学PEG试剂

击化学PEG试剂叠氮-聚乙二醇-马来酰亚胺&#xff0c;该化学试剂其英文名为Azdio-PEG-Maleimide&#xff0c;&#xff08;N3-PEG-MAL&#xff09;。所属分类为&#xff1a;Azide PEG Maleimide PEG。 化学试剂叠氮-PEG-马来酰亚胺的分子量均可定制&#xff0c;有&#xff1a;N3…