JavaSE【继承和多态】(2)(向上转型、向下转型、重写、动态绑定、静态绑定、多态的运用)

news2024/9/24 21:17:02

一、多态

1.多态的概念

多态的概念:通俗来说,就是多种形态, 具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状 态。
简单说就是,同一件事情,发生在不同对象身上,就会产生不同的结果。
多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法 

2.多态实现条件

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

1. 必须在继承体系下,向上转型

2. 子类必须要对父类中方法进行重写

3. 通过父类的引用调用重写的方法

完成以上3步,就会发生动态绑定,动态绑定就是多态的基础

二、向上转型 、向下转型

1)向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。

常见的3个向上转型的时机:
1.直接赋值     : 语法格式:父类类型 对象名 = new 子类类型 ()
2.方法的参数,传参的时候
3.返回值 
class Animal{
    public String name;
    public int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(this.name+"正在吃饭!");
    }
}
class Dog extends Animal{

    public Dog(String name, int age) {
        //帮助初始化子类从父类继承过来的成员
        super(name, age);
    }

    public void bark(){
        System.out.println(this.name+"旺旺叫");
    }
}

 父类本身时只能调用自己的成员方法和成员变量

1.直接赋值时 - 向上转型

2. 调用函数传参时 - 向上转型

 3.返回值 向上转型

2)向下转型(不安全)

向下转型: 将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的
方法,此时:将父类引用再还原为子类对象即可,即向下转换

不安全的原因是:
         不同于向上转型,子类向上转型的父类是唯一的。
         而向下转型,父类下面的子类有多种,不唯一,不能保证向下转型的那一类就是之前向上转型的那个类。
例如:
         猫、狗 向上转型 动物(唯一)
        动物 向下转型 可以有 猫、狗、狼、马等(不唯一)
1)animal引用Dog,向上转型,狗是动物
然后dog引用animal,向下转型,刚刚好这个动物是狗,强制类型转换为Dog,再用dog接收
2)animal引用Dog,向上转型,狗是动物
然后Cat引用animal,向下转型,但此时这个动物是狗不是猫,强制类型转换为Cat
运行报错

 可以观察到:只有animal引用的对象是cat对象的实例

animal才能 向下转型 为cat

三、重写 - 父类和子类同名的方法 

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

如果在继承关系上,满足者3点

1.方法的返回类型一样

2.方法名一样

3.方法的参数列表一样

那么,就说这两个方法之间的关系是重写

重写的设计原则
对于已经投入使用的类,尽量不要进行修改。最好的方式是:重新定义一个新的类,来重复利用其中共性的内容,
并且添加或者改动新的内容。

1.一般来说  参数列表、 方法名 必须是一样的 ,返回值可以不同(但必须是父子关系)

1)参数列表 方法名 返回值 全都相同

没写子类eat方法时,父类调用的eat是自己的方法

 当子类有一个和父类同名的eat方法时(重写)

此时通过父类对象的引用,调用这个重写的方法

2)参数列表、方法名 相同,返回值 不同 。(称为:协变类型)

2.被重写的方法的访问修饰限定符( 子类要大于等于父类的)

private < 默认 < protected < public

如果父类是默认的,那么子类就只能是 默认 、protected 、 public。

 

3. 父类 private 、static、final、构造方法 不能被重写

1)被private修饰的方法 ,不能被重写

        因为本身private的范围就是,同一包中同一类

然后此时父类和子类是在两个不同的类中,固然错了。

2)被static修饰的方法,不能被重写

重写后的方法,最后是依赖父类对象来调用的,

而static不依赖于对象,而是用类来调用的,所以重写报错。

3)被final修饰的方法,不能被重写

        被final修饰,就表示这个类不能被继承。

而重写是在继承的基础上进行的,所以重写报错了。

4)构造方法不能被重写

        构造方法是每个类特有的,不能重写

4.避免在构造方法中调用重写的方法

        构造 D 对象的同时 , 会调用 B 的构造方法 .
        B 的构造方法中调用了 func 方法 , 此时会触发动态绑定 , 会调用到 D 中的 func
此时 D 对象自身还没有构造 , 此时 num 处在未初始化的状态 , 值为 0. 如果具备多态性, num 的值应该是 1.
        所以在构造函数内,尽量避免使用实例方法,除了fifinal private 方法。
结论 : " 用尽量简单的方式使对象进入可工作状态 ", 尽量不要在构造器中调用方法 ( 如果这个方法被子类重写 , 就会触 发动态绑定, 但是此时子类对象还没构造完成 ), 可能会出现一些隐藏的但是又极难发现的问题 .

 

5.建议重写之后,在重写的方法上面写一个@Override

这是一个注解,提示这个方法是重写的

 如果重写错误了,会给予提示

6.快捷键 生成 重写方法

按需要字节选择要重写的方法

回顾之前的 重写toString 方法

 ​​​​​

7.重写和重载的区别

 四、动态绑定 和 静态绑定

1.动态绑定:也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体 调用那个类的方法。

打开字节码文件

 在这个路径里,输入cmd

 找到main方法

2.静态绑定:也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用那个方法。

典型代表函数重载。

例如

 五、多态的应用

   当父类引用,引用的子类对象不一样的时候,调用这个重写的方法,所表现出来的行为时不一样的!
   这种思想就时 多态!!!

 

使用多态的好处
1. 能够降低代码的 " 圈复杂度 ", 避免使用大量的 if - else
什么叫 " 圈复杂度 " ?
        圈复杂度是一种描述一段代码复杂程度的方式. 一段代码如果平铺直叙 , 那么就比较简单容易理解 . 而如 果有很多的条件分支或者循环语句, 就认为理解起来更复杂 .
        因此我们可以简单粗暴的计算一段代码中条件语句和循环语句出现的个数, 这个个数就称为 " 圈复杂度 ".
        如果一个方法的圈复杂度太高, 就需要考虑重构 .
不同公司对于代码的圈复杂度的规范不一样 . 一般不会超过 10

 1.画图形

1)普通if方法

class Shape{
    public void draw(){
        System.out.println("画一个图形");
    }

}
class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("矩形");
    }
}
class Triangle extends Shape{
    @Override
    public void draw() {
        System.out.println("三角形");
    }
}
class Cycle extends Shape{
    @Override
    public void draw() {
        System.out.println("圆形");
    }
}
public class Test2 {
    public static void main(String[] args) {
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Triangle triangle = new Triangle();
        String[] strings = {"cycle","rect","cycle","rect","triangle"};

        for (String x:
             strings) {
            if(x.equals("cycle")){
                cycle.draw();
            } else if (x.equals("rect")) {
                rect.draw();
            }else {
                triangle.draw();
            }

        }
    }


}

 

2)多态方法

class Shape{
    public void draw(){
        System.out.println("画一个图形");
    }

}
class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("矩形");
    }
}
class Triangle extends Shape{
    @Override
    public void draw() {
        System.out.println("三角形");
    }
}
class Cycle extends Shape{
    @Override
    public void draw() {
        System.out.println("圆形");
    }
}
public class Test2 {
    public static void main(String[] args) {
//        Shape shape =  new Cycle();
//        Shape shape1 =  new Rect();
//        Shape shape2 =  new Triangle();
        Shape[] shapes = {new Cycle(),new Rect(),new Cycle(),new Rect(),new Triangle()};

        for (Shape shape:shapes){
            shape.draw();
        }
    }


}

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

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

相关文章

获取淘宝商品详情数据的几种方法(商品标题、商品价格、商品销量、详情图片、商品主图

淘宝作为中国最大的电商平台之一&#xff0c;拥有海量的商品信息和用户数据。对于电商从业人员和数据分析师来说&#xff0c;了解淘宝商品详情数据是非常重要的。本文将介绍几种获取淘宝商品详情数据的高效方法&#xff0c;并详细探讨每种方法的优缺点。 一、淘宝 API 淘宝开放…

SpringBoot整合邮件服务

SpringBoot整合邮件服务 发送邮件应该是网站的必备功能之一&#xff0c;什么注册验证&#xff0c;忘记密码或者是给用户发送营销信息。最早期的时候我们会 使用 JavaMail 相关 api 来写发送邮件的相关代码&#xff0c;后来 Spring 推出了 JavaMailSender 更加简化了邮件发送的…

无限遍历,Python实现在多维嵌套字典、列表、元组的JSON中获取数据

目录 背景 思路 新建两个函数A和B&#xff0c;函数 A处理字典数据&#xff0c;被调用后&#xff0c;判断传递的参数&#xff0c;如果参数为字典&#xff0c;则调用自身&#xff1b; 如果是列表或者元组&#xff0c;则调用列表处理函数B&#xff1b; 函数 B处理列表&#x…

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)【三】

文章目录 SSM(Vue3ElementPlusAxiosSSM前后端分离)--基础环境搭建【三】项目介绍项目功能/界面● SSM 整合项目界面 配置Spring 和MyBatis , 并完成整合 SSM(Vue3ElementPlusAxiosSSM前后端分离)–基础环境搭建【三】 项目介绍 项目功能/界面 ● SSM 整合项目界面 配置Sprin…

C盘满了怎么办怎么清理

我的c盘只有128GB&#xff0c;由于工作需要安装的软件较多&#xff0c;虽然已经将软件等资料全部放到其它盘中&#xff0c;可是c盘却总是清理不及。 很多软件不能卸载&#xff0c;可是删除文件腾出的空间太有限了。 今天终于找到一个清理的新方法。 1、打开资源管理器&#x…

Java实现保证多个线程执行完毕再往下执行操作

要实现该需求可借助线程池的awaitTermination和isTerminated方法来实现&#xff0c;也可使用CountDownLatch计数器来实现。 1.使用awaitTermination方法阻塞主线程, 直至线程池关闭 public static void main(String[] args) throws InterruptedException {ExecutorService thr…

【逗老师的PMP学习笔记】引论篇

那个啥都学啥都研究的逗老师&#xff0c;最近开始学PMP了。 随笔记一记学习记录。 项目的基本知识 1、项目的特性 独特性渐进性临时性项目创造价值项目驱动变革项目满足组织需要 引申一点&#xff0c;项目-运营&#xff0c;工作中我们需要思考这两者的区别。 比如逗老师天天…

SpringSecurity5.7+最新案例 -- 用户名密码+验证码+记住我······

简介 根据最近一段时间的设计以及摸索&#xff0c;对SpringSecurity进行总结&#xff0c;目前security采用的是5.7版本&#xff0c;和以前的版本最大的差别就是&#xff0c;以前创建SecurityConfig需要继承WebSecurityConfigurerAdapter&#xff0c;而到了5.7以后&#xff0c;…

【2023全网最全最火教程】Web UI自动化测试之元素定位(超详细~)

目前&#xff0c;在自动化测试的实际应用中&#xff0c;接口自动化测试被广泛使用&#xff0c;但UI自动化测试也并不会被替代。让我们看看二者的对比&#xff1a; 接口自动化测试是跳过前端界面直接对服务端的测试&#xff0c;执行效率和覆盖率更高&#xff0c;维护成本更低&a…

做完两年外包,感觉自己废了一半....

先说一下自己的情况。大专生&#xff0c;17年通过校招进入湖南某软件公司&#xff0c;干了接近2年的点点点&#xff0c;今年年上旬&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了五年的功能测试…

C/C++的5大内存分区

1、堆区&#xff08;heap&#xff09;——由程序员分配和释放&#xff0c; 若程序员不释放&#xff0c;程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事 2、栈区&#xff08;stack&#xff09;——由编译器自动分配释放 &#xff0c;存放函数的参数值&#xff0c;局…

linux 查看磁盘大小 内存 目录下各目录大小

查看当前服务器挂在的磁盘大小及已使用、可使用、使用占比、磁盘对应的目录等 df -TH 查看当前目录下 各子目录或文件的大小&#xff1a;右边是目录或文件名&#xff0c;左边是占用的大小 du -sh * 使用 rm命令删除目录或文件&#xff1a;删了数据找不回来&#xff0c;&#x…

阿里巴巴国际站、速卖通如何通过测评补单打造爆款产品?

在现如今竞争激烈的跨境电商行业中&#xff0c;测评补单虽然被认为是公开的秘密&#xff0c;但无论是消费者还是官方都对其持反感和不屑的态度。然而&#xff0c;在互联网时代&#xff0c;如果产品价格、运营等没有绝对的优势&#xff0c;尤其对于新手店铺&#xff0c;要在市场…

性能测试怎么做?测试工具怎么选择?

在当前软件测试行业&#xff0c;熟练掌握性能测试已经是测试工程师们面试的敲门砖了&#xff0c;当然还有很多测试朋友们每天的工作更多的是点点点&#xff0c;性能方面可能也只是做过简单的并发测试&#xff0c;对于编写脚本&#xff0c;搭建环境方面也比较陌生。今天这篇文章…

Qt+联想电脑管家

1.自定义按钮类 效果&#xff1a; (1)仅当未选中&#xff0c;未悬浮时 (2)其他三种情况&#xff0c;均如图 #ifndef BTN_H #define BTN_H#include <QPushButton> class btn : public QPushButton {Q_OBJECT public:btn(QWidget * parent nullptr);void set_normal_icon(…

十分钟python入门 日期时间

1.Python 日期 Python 中的日期不是其自身的数据类型&#xff0c;但是我们可以导入名为 datetime 的模块&#xff0c;把日期视作日期对象进行处理。 1.1 导入 datetime 模块并显示当前日期&#xff1a; import datetime#导入 datetime 模块并显示当前日期&#xff1a; x da…

Dockerfile构建apache镜像 下载源码

创建工作目录 [rootlocalhost ~]# mkdir tomcat [rootlocalhost ~]# cd tomcat/ 编写配置文件 [rootlocalhost tomcat]# cat Dockerfile #基于的基础镜像 FROM centos:7 #镜像作者信息 MAINTAINER liu <wewed163.com> #安装相关依赖包 RUN yum install -y wget net-…

python与深度学习(十五):CNN和宝可梦模型

目录 1. 说明2. 宝可梦模型2.1 导入相关库2.2 建立模型2.3 模型编译2.4 数据生成器2.5 模型训练2.6 模型保存 3. 宝可梦的CNN模型可视化结果图4. 完整代码5. 宝可梦的迁移学习 1. 说明 本篇文章是CNN的另外一个例子&#xff0c;宝可梦模型&#xff0c;是自制数据集的例子。之前…

从C语言到C++_30(哈希)闭散列和开散列(哈希桶)的实现

目录 1. 哈希结构 1.1 哈希的概念 1.2 哈希冲突(碰撞) 1.3 哈希函数 2. 闭散列/开散列解决哈希冲突 2.1 闭散列概念和代码 2.1.1 闭散列线性探测&#xff08;实现&#xff09; 闭散列线性探测完整代码 2.1.2 闭散列二次探测&#xff08;了解&#xff09; 2.2 开散列(…

无边界野望:高通也有痛点?

外界给予高通的称呼无非是性价屠夫&#xff0c;因为即可“拳打”联发科&#xff0c;又能四度包下上海ChinaJoy展馆做游戏技术支持的王者&#xff0c;对高通来说它的路是无边界的&#xff0c;也是跨界之路上前行的“诗和远方”。 这里&#xff0c;既有生成式AI在终端侧布局、与…