面向对象程序之多态

1.多态的概念

简单来说,就是多种形态,具体点就是去完成某个行为,不同的对象去完成会有不同的形态。

举个例子:对于动物,他们吃的都是食物,但狗吃的是狗粮,猫吃的是猫粮,去完成吃这个行为,不同的对象会产生不同的形态。

2.多态实现条件

实现多态,必须满足下面几个条件,缺一不可:

1.必须在继续体系下

2.子类必须要对子类中的方法重写

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

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

2.1向上转型

我们把子类的对象给父类,这种就叫做向上转型

格式:父类类型 对象名 =new 子类类型()

[Animal animal = new Cat("小黄",2);]

向上转型的优点:让代码实现更简单灵活。

向上转型的缺陷:不能调用到子类特有的方法

向上转型可能发生的几种情况

1. 直接赋值 2. 方法传参 3. 方法返回

我们来看个例子:依旧是猫和狗。在这个代码中,我们把子类的对象给父类,这就实现了向上转型,但要注意的是,虽然把子类的对象给了父类,但是在调用方法是,只能调用父类中的方法。

那如果我们想要给父类中的成员变量赋值,那么就需要在子类和父类中加构造方法去调用super语句,为其赋值。 

package com.bai.demo2;

class Animal1{
    public String name;
    public int age;
    public Animal1(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void sleep(){
        System.out.println(this.name+"正在睡觉");
    }
}

class Dog1 extends Animal1{
    public Dog1(String name,int age){
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name+"吃东西");
    }
}

class Cat1 extends Animal1{
    public Cat1(String name,int age){
        super(name,age);
    }
    public void bark(){
        System.out.println(this.name+"正在叫");
    }
}

public class demot {
    public static void main(String[] args) {
        Animal1 animal=new Dog1("小黄",2);
        animal.sleep();
      //  animal.bark();//因为animal中并无bark方法,所以不能访问,编译器报错
    }
}

结果:小黄正在睡觉 

2.2方法的重写

重写也叫覆盖,重写是子类对父类非静态、非private修饰、非final修饰,非构造方法等的实现过程进行重新编写,返回值和形参都不能变(即外壳不变,核心重写

重写的好处就是在于子类可以根据自己的需要,定义特定于自己的行为,也就是子类能过根据需要实现父类的方法。 

重写的规则:

1. 被重写的方法返回值可以不同,但必须是具有父子关系的

2.子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致

3.访问权限不能比父类中被重写的方法的访问权限更低

4.父类被static,private修饰的方法、构造方法都不能被重写

在重写的时候,可以加上@Override来注释来显式指定。有这个注释,能帮我们进行一些合法性的检验。

例子:

    
    class Animal1{
        public String name;
        public int age;
        public Animal1(String name,int age){
            this.name=name;
            this.age=age;
        }
        public void eat(){
            System.out.println(this.name+"正在吃东西");
        }
    }
    
    class Dog1 extends Animal1{
        public Dog1(String name,int age){
            super(name,age);
        }
        public void eat(){
            System.out.println(this.name+"吃狗粮");
        }
    }
    
    class Cat1 extends Animal1{
        public Cat1(String name,int age){
            super(name,age);
        }
        public void eat(){
            System.out.println(this.name+"吃猫粮");
        }
    }
    
    public class demot {
        public static void main(String[] args) {
            Animal1 animal=new Dog1("小黄",2);
            animal.eat();
        }
    }
结果:小黄吃狗粮
我们可以看到,我们虽然调用的是父类的eat,但实际输出的是子类的方法,这就是动态绑定

 动态绑定发生的条件:1.发生向上转型 2.方法重写

静态绑定:在编译的时候就已经知道要执行哪个方法了

2.3重写(override)和重载(overload)的区别

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

下面是方法重载的例子

 方法的重写在上面猫和狗动态绑定就是

2.4向下转型

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

例子:

class Animal2{
    public String name;
    public int age;
    public Animal2(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void eat(){
        System.out.println(this.name+"正在吃东西");
    }
    public void sleep(){
        System.out.println(this.name+"正在睡觉");
    }
}

class Dog2 extends Animal2{
    public Dog2(String name,int age){
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name+"吃狗粮");
    }
}

class Cat2 extends Animal2{
    public Cat2(String name,int age){
        super(name,age);
    }
    public void bark(){
        System.out.println(this.name+"正在叫");
    }
    public void eat(){
        System.out.println(this.name+"吃猫粮");
    }
}

public class test3 {
    public static void main(String[] args) {
        Animal2 a1=new Dog2("动物",1);
        Cat2 c2=(Cat2)a1;
        c2.bark();
    }
}

上面的代码,向下转型后会出现类型异常,a1和2的类型不同,所以会异常 。

向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。Java中为了提高向

目录

1.多态的概念

2.多态实现条件

2.1向上转型

2.2方法的重写

2.3重写(override)和重载(overload)的区别

2.4向下转型

2.5使用多态的好处


下转型的安全性,引入 了instanceof,如果该表达式为true,则可以安全转换。


class Animal2{
    public String name;
    public int age;
    public Animal2(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void eat(){
        System.out.println(this.name+"正在吃东西");
    }
    public void sleep(){
        System.out.println(this.name+"正在睡觉");
    }
}

class Dog2 extends Animal2{
    public Dog2(String name,int age){
        super(name,age);
    }
    public void eat(){
        System.out.println(this.name+"吃狗粮");
    }
}

class Cat2 extends Animal2{
    public Cat2(String name,int age){
        super(name,age);
    }
    public void bark(){
        System.out.println(this.name+"正在叫");
    }
    public void eat(){
        System.out.println(this.name+"吃猫粮");
    }
}

public class test3 {
    public static void main(String[] args) {
        Animal2 a1=new Dog2("欧狗",1);
        if(a1 instanceof Cat2){
            Cat2 c2=(Cat2)a1;
            c2.bark();
        }
        System.out.println("=========");
        Animal2 a2=new Cat2("欧猫",1);
        if(a2 instanceof Cat2){
            Cat2 c3=(Cat2)a2;
            c3.bark();
        }

    }
}


2.5使用多态的好处

1. 能够降低代码的 "圈复杂度", 避免使用大量的 if - else

2. 可扩展能力更强 如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低.

多态缺陷:代码的运行效率降低。

1. 属性没有多态性 当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性

2. 构造方法没有多态性

面型对象重的三个特性先到这。

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

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

相关文章

lua脚本在redis集群中哈希槽分片问题

上文说到,通过用redis lua脚本实现时间窗分布式限流 可以操作redis lua脚本来实现时间窗限流,在执行lua脚本的时候,参数中有个keys列表,当lua脚本中如果有操作多个key的情况,就可以传个key列表了。通常情况下&#xff…

Java封装最佳实践:打造高内聚、低耦合的优雅代码~

​ 个人主页:秋风起,再归来~ 文章专栏:javaSE的修炼之路 个人格言:悟已往之不谏,知来者犹可追 克心守己,律己则安! 1、封装 1.1 封装的概念 面向对象程序三大…

python练习二

# Demo85def pai_xu(ls_test):#创建一个列表排序函数命名为pai_xu# 对创建的函数进行注释"""这是一个关于列表正序/倒序排列的函数:param ls_test: 需要排序的列表:return:"""ls1 [int(ls_test[i]) for i in range(len(ls_test))]#对input输入的…

surfer绘制等值线图

surfer介绍 Surfer软件,是美国Golden Software公司编制的一款以画三维图的软件。该软件具有强大的插值功能和绘制图件能力,可用来处理XYZ数据,是地质工作者常用的专业成图软件(来源于百度百科)。 surfer可以用来绘制…

计算机网络—TCP协议详解:特性、应用(1)

🎬慕斯主页:修仙—别有洞天 ♈️今日夜电波:マリンブルーの庭園—ずっと真夜中でいいのに。 0:34━━━━━━️💟──────── 3:34 🔄 ◀️…

Java中常见的锁策略

目录 乐观锁 vs 悲观锁 悲观锁: 乐观锁: 重量级锁 vs 轻量级锁 ⾃旋锁(Spin Lock) 公平锁 vs 非公平锁 可重⼊锁 vs 不可重入锁 读写锁 乐观锁 vs 悲观锁 悲观锁: 总是假设最坏的情况,每次去拿数据的时候都认为别…

3d整体模型怎么拆图---模大狮模型网

3D整体模型怎么拆图 一、模型准备 在进行3D整体模型的拆图之前,首先需要确保模型的构造清晰明了,各个部件之间的连接关系明确,并且模型的层级结构已经建立完成。 二、确定拆图方式 拆解方向:根据模型的结构和设计需求&#xff…

教你用Fiddler捕获HTTPS请求

安装Fiddler 这里不特别说明了,网上搜索一大把,根据安装引导一步步安装即可。(这里采用的是fiddler v4.6) 配置Fiddler 1、打开fiddler配置Tools –>Telerik Fiddler Options。 2、打开HTTPS配置项,勾选“Captur…

Leetcode-2580-统计将重叠区间合并成组的方案数-c++

题目详见https://leetcode.cn/problems/count-ways-to-group-overlapping-ranges/ 题目要求将最后的ranges分为两个组。也就是说当你的ranges已经满足题目要求的时候,这两个组怎么分是随意的,这里也就引出了 2 k 2^k 2k 的由来,其实就是每组…

Leetcode-2810-故障键盘-c++

题目详见https://leetcode.cn/problems/faulty-keyboard/ 题解 这道题的关键是如何合理地使用STL,毕竟是一道简单题。 之前常用到的Vector容器是单向开口的连续内存空间 deque则是一种双向开口的连续线性空间,又称双端动态数组。所谓的双向开口&#x…

Windows Server 2022 使用ApacheDS用户远程桌面登录服务器

Windows Server 2022 使用ApacheDS用户远程桌面登录服务器 1、接上篇 Windows Server 2022 使用ApacheDS用户认证 使用Administrator用户远程登录192.168.1.100windows server,打开pGina软件 2、输入刚刚在ApacheDS中的新添加的用户测试一下,会自动添加…

200个有趣的HTML前端游戏项目合集(持续更新中)

💂 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】🤟 一站式轻松构建小程序、Web网站、移动应用:👉注册地址🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交…

[实时流基础 flink] 窗口

在批处理统计中,我们可以等待一批数据都到齐后,统一处理。但是在实时处理统计中,我们是来一条就得处理一条,那么我们怎么统计最近一段时间内的数据呢?引入“窗口”。 文章目录 6.1 窗口的概念6.2 窗口的分类**1&#x…

让接口自动化测试更简单

HTTP 接口测试很简单,不管工具、框架、还是平台,只要很的好的几个点就是好工具。 测试数据问题:比如删除接口,重复执行还能保持结果一致,必定要做数据初始化。接口依赖问题:B 接口依赖 A 的返回值&#xf…

新model开发记录

模型使用 -- 用blender导出为 fbx ,修改渲染方式(点击模型->Materials->Extract Materials(将材质从fbx中 单独提取出来了)->Materials 选择 Shader -> SimpleURPToonLitExample 点开脸的材质,勾选第一条) 解决角色…

【C++的奇迹之旅(二)】C++关键字命名空间使用的三种方式C++输入输出命名空间std的使用惯例

文章目录 📝前言🌠 C关键字(C98)🌉 命名空间🌠命名空间定义🌉命名空间使用 🌠命名空间的使用有三种方式:🌉加命名空间名称及作用域限定符🌠使用using将命名空间中某个成员…

MATLAB绘制堆叠填充图--巧用句柄

MATLAB绘制堆叠填充图–巧用句柄 目录 MATLAB绘制堆叠填充图--巧用句柄1. 主要原理讲解1.1 主要函数1.2 句柄原理 2. 绘图示例2.1 准备数据2.2 绘制堆叠填充图-使用句柄控制图形属性2.3 设置填充颜色和样式2.4 添加标题和标签2.5 绘图效果 3. 结语 堆叠填充图是一种常见的数据可…

StringBuffer与StringBuilder

1.区别 (1). String : 不可变字符序列. (2). StringBuffer : 可变字符序列.线程安全,但效率低. (3). StringBuilder : 可变字符序列.线程不安全,但效率高. 既然StringBuffer与StringBuilder都是可变字符序列,但二者咋区分开呢&#xff1f…

Dimitra:基于区块链、AI 等前沿技术重塑传统农业

根据 2023 年联合国粮食及农业组织(FAO)、国际农业发展基金(IFAD)等组织联合发布的《世界粮食安全和营养状况》报告显示,目前全球约有 7.35 亿饥饿人口,远高于 2019 年的 6.13 亿,这意味着农业仍…

碳素光线疗法与宠物健康

碳素光线与宠物健康 生息在地球上的所有动物、在自然太阳光奇妙的作用下、生长发育。太阳光的能量使它们不断进化、繁衍种族。现在、生物能够生存、全仰仗于太阳的光线。太阳光线中、包含有动物健康所需要的极为重要的波长。因此、和户外饲养的动物相比、在室内喂养的观赏动物、…