3.1.8 多态

news2024/9/29 1:29:29

文章目录

  • 1.概念
  • 2.特点
  • 3.入门案例练习
  • 4 多态的好处
  • 5 多态的使用
  • 6 练习:多态成员使用测试
  • 7 拓展
    • 7.1 综合案例
    • 7.2 多态为了统一调用标准
    • 7.3 静态变量和实例变量的区别
    • 7.4 向上转型和向下转型


1.概念

多态是面向对象程序设计(OOP)的一个重要特征,指同一个实体同时具有多种形式,即同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
可以把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,统一调用标准。
比如,你的女盆友让你买点水果回来,不管买回来的是苹果还是西瓜,只要是水果就行,这个就是生活中多态的体现。
再比如,小猫、小狗、小猪我们可以把他们都归纳成小动物,每种小动物都需要吃东西,所以我们可以统一设置他们都必须吃,但是每种小动物的习性不一样,那这个就可以设置成小动物自己特有的功能,多态对象只能调用父类中定义子类中重写的功能,并不能调用子类的特有功能,这样就实现了代码的统一。

2.特点

  1. 多态的前提1:继承
  2. 多态的前提2:要有方法的重写
  3. 父类引用指向子类对象,如:Animal a = new Cat();
  4. 多态中,编译看左边,运行看右边
    在这里插入图片描述

3.入门案例练习

package partTwo;
/* 本类用于多态的入门案例*/
public class TestDemo {
    public static void main(String[] args) {
        //6.创建"纯纯”的对象进行测试(为了好理解,就是直接创建对象)
        Animal2 a = new Animal2();
        Cat2 c = new Cat2();
        Dog d = new Dog();
        //调用方法进行测试
        a.eat();  //小动物Animal吃啥都行
        c.eat();  //小猫爱吃小鱼干,执行子类重写后的功能
        d.eat();  //小狗爱吃肉骨头,执行子类重写后的功能

        /*2.子类可以调用子类的功能,但是父类不能调用子类的特有功能*/
        //a.jump();

        c.jump();  //子类对象可以调用自己的功能
        d.run();   //子类对象可以调用自己的功能

        //8.创建多态进行测试
        /* 3.口诀1:父类引用指向子类对象
         * 解释:创建出来的子类对象地址值,交给父类类型的引用类型变量来保存*/
        Animal2 a2 = new Cat2();
        Animal a3 = new Dog();
        a2.eat();
        a3.eat();
        /*4.口诀2:编译看左边,运行看右边
         * 解释:必须要在父类里定义这个方法,才能通过编译
         * 编译时,把多态对象看做父类,必须要在子类中重写父类定义的方法
         * 运行时,方法体使用的是子类的功能*/
        //a2.jump()   报错,无法使用,不是父类功能的重写,父类中未定义此功能
        //a3.run();    报错,无法使用,不是父类功能的重写,父类中未定义此功能
    }
}


/* 1.多态的前提:继承+重写*/
//1.创建父类
class Animal2{
    //3.创建父类的普通方法
    public void eat(){
        System.out.println("小动物Animal吃啥都行");
    }
}


//2.1创建子类小猫
class Cat2 extends Animal2{
    //4.1重写父类的功能--小鱼干
    @Override
    public void eat(){
        System.out.println("小猫爱吃小鱼干");
    }
    //5.1 添加子类的特有功能
    public void jump(){
        System.out.println("小猫Cat跳的老高了");
    }
}

//2.2创建子类小狗
class Dog extends Animal{
    //4.2重写父类的功能--肉骨头
    @Override
    public void eat(){
        System.out.println("小狗爱吃肉骨头");
    }
    //5.2添加子类的特有功能
    public void run(){
        System.out.println("小狗Dog跑的老快了");
    }
}

4 多态的好处

  1. 多态可以让我们不用关心某个对象到底具体是什么类型,就可以使用该对象的某些方法
  2. 提高了程序的可扩展性和可维护性

5 多态的使用

前提:多态对象把自己看做是父类类型

  1. 成员变量: 使用的是父类的
  2. 成员方法: 由于存在重写现象,所以使用的是子类的
  3. 静态成员: 随着类的加载而加载,谁调用就返回谁的

6 练习:多态成员使用测试

package partTwo;
/* 本类用于测试多态成员的使用情况*/
public class TestDemo2 {
    public static void main(String[] args) {
        // 创建纯纯的子类对象
        Dog3 d = new Dog3();
        System.out.println(d.sum);  //20   子类自己的属性
        d.eat(); // 子类自己的方法
        d.play(); //小狗玩皮球

        //8.创建多态对象
        /* 口诀1 :父类引用指向子类对象
         *  口诀2 :编译(保存)看左边,运行(测试)看右边*/
        Animal3 a = new Dog3();
        /* 多态中,成员变量使用的是父类的*/
        System.out.println(a.sum); //10
        /* 多态中,方法的声明的使用的是父类的,方法的实现使用的是子类的*/
        a.eat();  //小狗要吃肉包子
        /* 多态中,如果父子类都有同名的静态方法,使用的是父类的*/
        a.play();  //玩啥都行,静态方法优先级最大,不能被重写
    }
}
//1.创建父类
class Animal3{
    //3.创建成员变量
    int sum = 10;
    //4.创建普通方法
    public void eat(){
        System.out.println("吃啥都行");
    }

    //创建父类的静态方法
    public static void play(){
        System.out.println("玩啥都行");
    }
}

/* 1.多态的前提:继承+重写*/
//2.创建子类
class Dog3 extends Animal3{
    //5.定义子类的成员变量
    int sum = 20;
    //6. 重写父类的方法
    @Override /* 2.此注解表示当前是一个重写的方法*/
    public void eat(){
        System.out.println("小狗要吃肉包子");
    }
    //创建子类的静态方法
    /* @Override  这不是一个重写的方法,质数恰巧在俩个类中,出现了俩个一模一样的方法
       静态方法属于类资源,不存在重写现象所以,在哪个类里定义,就在哪个类里使用*/
    public static void play(){
        System.out.println("小狗玩皮球");
    }
}

7 拓展

7.1 综合案例

package partTwo;
/* 本类用于汽车设计综合案例*/
public class TestCar2 {
    public static void main(String[] args) {
        //9.创建一个纯纯的对象
        Car2 c = new Car2();
        System.out.println(c.getColor()); //null 被封装了需要使用get方法
        c.start(); //我的车车启动了   使用的父类自己的功能
        c.stop();  //我的车车熄火了   使用的父类自己的功能
        //c.swim();  会报错,父类不能使用子类的特有功能

        BMW b = new BMW();
        System.out.println(b.color); //子类自己的值
        System.out.println(b.getColor());  //父类设置的值
        b.start(); //重写后的功能
        b.stop();  //没有重写,输出的为继承父类的功能

        //11.创建多态对象进行测试
        Car2 c2 = new TSL();
        // System.out.println(c2.color); 父类被封装的color属性,只能在本类使用
        System.out.println(c2.getColor()); //可以调用公共get方法使用
        c2.stop(); //调用的是重写后的属性
        c2.start();  //没有重写,调用的是父类的声明
        //c2.swim();  会报错,多态对象不能使用子类的特有功能,因为它认为自己是父类型
    }
}
//1.通过分析,抽象形成一个汽车类
class Car2 {
    //2.定义属性--成员变量
    //2.1 封装属性--使用private
    private String brand;  //品牌
    private String color;  //颜色
    private int id;  //编号
    private double length;  //车长

    //3.定义方法--功能
    public void start(){
        System.out.println("我的车车启动了");
    }
    public void stop(){
        System.out.println("唉呀妈呀,熄火了");
    }

    //2.2 生成属性对应get,set值
    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }
}

//4.创建一个子类--宝马类
class BMW extends Car2{
    //8.1 定义自己的特有属性
    String color = "五彩斑斓的黑";
    //6.重写父类的方法
    @Override
    public void start(){
        // System.out.println(getColor());  被封装的,使用的话,要调用getcolor
        System.out.println("我的车要起飞了");
    }
}
//5创建一个子类--特斯拉
class TSL extends Car2{
    //8.2 定义自己的特有属性
    String color = "炫彩夺目的红";
    @Override
    public void stop(){
        System.out.println("唉呀妈呀,咋停不下来呢");
    }
    //7.定义子类的特有功能
    public void swim(){
        System.out.println("没想到吗,我还是一个潜水艇");
    }
}

7.2 多态为了统一调用标准

package partTwo;

public class TestFruit {
    public static void main(String[] args) {
        Fruit2 f = new Fruit2();
        Apple2 a = new Apple2();
        Orange o = new Orange();
        get(f);
        get(a);
        get(o);
    }
    //只需要创建一个方法,就可以执行截然不同的效果
    //忽略子类对象的差异统一看作父类类型
    public static void get(Fruit2 f){
        f.clean();
    }
}
class Fruit2{
    public void clean(){
        System.out.println("水果要洗洗再吃");
    }
}
class Apple2 extends Fruit2{
    @Override
    public void clean(){
        System.out.println("苹果需要削皮");
    }
}
class Orange extends Fruit2{
    @Override
    public void clean(){
        System.out.println("橙子需要剥皮");
    }
}

7.3 静态变量和实例变量的区别

在语法定义上的区别:
- 静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:
- 实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

7.4 向上转型和向下转型

在JAVA中,继承是一个重要的特征,通过extends关键字,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。
那么在这个过程中就存在着多态的应用。存在着两种转型方式,分别是:向上转型和向下转型。
向上转型:可以把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,统一调用标准。
比如:父类Parent,子类Child
父类的引用指向子类对象:Parent p=new Child();
说明:向上转型时,子类对象当成父类对象,只能调用父类的功能,如果子类重写了父类中声明过的方法,方法体执行的就是子类重过后的功能。但是此时对象是把自己看做是父类类型的,所以其他资源使用的还是父类型的。
比如:花木兰替父从军,大家都把花木兰看做她爸,但是实际从军的是花木兰,而且,花木兰只能做她爸能做的事,在军营里是不可以化妆的。

向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。这个是之前向上造型过的子类对象仍然想执行子类的特有功能,所以需要重新恢复成子类对象
Parent p = new Child();//向上转型,此时,p是Parent类型
Child c = (Child)p;//此时,把Parent类型的p转成小类型Child
其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的
说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。
比如:花木兰打仗结束,就不需要再看做是她爸了,就可以”对镜贴花黄”了

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

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

相关文章

【数据结构初阶】第三篇——单链表

链表的概念及其结构 初始化链表 打印单链表 增加结点 头插 尾插 在给定位置之前插入 在给定位置之后插入 删除结点 头删 尾删 删除给定位置的结点 查找数据 修改数据 链表的概念及其结构 基本概念 链表是一种物理存储结构上非连续,非顺序的存储结构&a…

盘点保护隐私安全的浏览器,密码锁屏这个功能,真香

在互联网时代,大家都比较关心自己的隐私安全。一些互联网公司和在线客服会跟踪用户的在线活动,收集用户的个人信息,有时候甚至因为个人的不良习惯导致信息泄露,因此选择隐私和安全性好的浏览器尤其重要。下面给大家介绍隐私安全做…

大数据技术架构(组件)11——Hive:日期函数

1.4.5、日期函数1.4.5.1、from_unixtimeselect from_unixtime(1638602968),from_unixtime(1638602968,yyyy-MM-dd HH:mm:SS),from_unixtime(1638602968,yyyy-MM-dd);1.4.5.2、unix_timestampselect unix_timestamp();1.4.5.3、to_dateselect to_date(2021-12-04 2021-12-04 15:…

【授权与认证】OAuth 2.0 和 OIDC 的异同点

开发者谈 | OAuth 2.0 和 OIDC 协议的关系?(内含必看案例) 【Web 安全】CSRF 攻击详解 OAuth 2.0 OAuth 2.0 的一个简单解释OAuth 2.0 的四种方式什么是Oauth2.0,Oauth2.0的四种授权模式 简单说,OAuth 就是一种授权…

【前端】Vue项目:旅游App-(16)home+hooks:窗口滚动到底部动态加载新数据、抽取到hook

文章目录目标过程与代码监听窗口的滚动窗口上事件监听的移除封装到一个hook回调函数法(不推荐)返回值法(推荐)效果总代码修改或添加的文件hooks的useScrollhome-content参考本项目博客总结:【前端】Vue项目&#xff1a…

git 使用tag

文章目录概述示例创建标签 tag查看tag删除本地标签推送标签git 根据tag创建分支回退到tag参考概述 常常为发布上线某个版本打上一个标签,表示这是什么版本,这样后续找起来就很方便。 如果没有标签只能通过commit历史去查找,而且commit版本显…

每日学术速递1.30

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 更多Ai资讯: 今天带来的arXiv上最新发表的3篇文本图像的生成论文。 Subjects: cs.LG、cs.Cv、cs.AI、cs.CL 1.StyleGAN-T: Unlocking the Power of GANs for Fast Large-Scale Text-to-Im…

Spire.Doc for Java v11.1.1 Patch

Spire.Doc for Java是一个专业的 Word API,它使 Java 应用程序能够在不依赖 Microsoft Word 的情况下创建、转换、操作和打印 Word文档。 通过使用这个多功能库,开发人员能够毫不费力地处理大量任务,例如插入图像、超链接、 数字签名、书签和…

Mybatis-plus(下)

一,乐观锁可参考官方文档:https://baomidou.com/pages/0d93c0/场景:当两个工作人员同时去处理一条投诉工单的时候当两个人一起点开了投诉工单详情 并一起编辑处理 随后同时反馈给用户时 此时就会出现矛盾 当系统正常 没有bug的时候 是会出现两…

SpringCloud_Sleuth分布式链路请求跟踪

目录一、概述1.为什么会出现这个技术?需要解决哪些问题?2.是什么3.解决二、搭建链路监控步骤1.zipkin2.服务提供者3.服务消费者(调用方)4.依次启动eureka7001/8001/805.打开浏览器访问: http://localhost:9411一、概述…

网络流量监控对DMS系统排错分析案例

背景 DMS系统是某汽车集团的经销商在线系统,是汽车集团的重要业务系统。本次分析重点针对DMS系统性能进行分析,以供安全取证、性能分析、网络质量监测以及深层网络分析。 该汽车总部已部署NetInside流量分析系统,使用流量分析系统提供实时和…

Qt扫盲-QDebug理论总结

QDebug理论使用总结一、概述二、使用1. 基础使用2. 格式化选项3.将自定义类型写入流一、概述 每当开发人员需要将调试或跟踪信息写入设备、文件、字符串或控制台时,都会使用QDebug。这个就可以方便我们调试,基本上Qt所有的内容都能通过调试打印出来&…

14.重载运算与类型转换

文章目录重载运算与类型转换14.1基本概念直接调用一个重载的运算符函数某些运算符不应该被重载使用与内置类型一致的含义赋值和复合赋值运算符选择作为成员或者非成员14.2输入和输出运算符14.2.1重载输出运算符<<输出运算符尽量减少格式化操作输入输出运算符必须是非成员…

智能家居之主机---计划筹备

智能家居之主机---计划筹备前言绪言前期构思硬件平台结构平台前言 绪言 感觉有一年多没发过文章了&#xff0c;这一年多太忙了&#xff0c;来到新的公司后要学的太多了&#xff0c;代码风格&#xff0c;架构&#xff0c;操作系统&#xff0c;各种通讯协议&#xff0c;伺服驱动…

解决问题的方法论

概述 解决问题的能力是职场中最重要的能力之一&#xff0c;如何逻辑清晰、效率满满的解决问题&#xff0c;可参考以下4个步骤。 一、准确的界定问题 找出真正的问题。 准确的界定问题&#xff0c;避免被表面现象所迷惑。 《麦肯锡工具》中&#xff0c;给出一个标准的步骤&am…

【数据手册】LM1117L3芯片的使用

1.特征 可调或固定输出1A输出电流低损耗&#xff0c;在1A输出电流时最大电压为1.3V0.04%的线路调节0.2%负载调节100%热极限燃烧快速瞬态响应 2.描述 LM1117系列正可调和固定调节器设计提供1A高电流效率。所有内部电路设计为低至1.3V输入输出差。片内微调将参考电压调整为1% 3…

【微服务】RabbitMQSpringAMQP消息队列

&#x1f6a9;本文已收录至专栏&#xff1a;微服务探索之旅 &#x1f44d;希望您能有所收获 一.初识MQ (1) 引入 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;可以立即得到响应&#xff0c;但是你却不能跟多个人同时通话。 异…

leedcode刷题 | 详细注释 | 调用+调试 C++

目录1.两数之和题目C代码2.两数相加题目代码3. 无重复字符的最长子串题目&#xff1a;代码&#xff1a;4. 合并两个有序数组题目&#xff1a;代码&#xff1a;5.寻找两个正序数组的中位数题目&#xff1a;代码&#xff1a;1.两数之和 题目 给定一个整数数组 nums 和一个整数目…

API 网关策略的二三事

作者暴渊&#xff0c;API7.ai 技术工程师&#xff0c;Apache APISIX Committer。 近些年随着云原生和微服务架构的日趋发展&#xff0c;API 网关以流量入口的角色在技术架构中扮演着越来越重要的作用。API 网关主要负责接收所有请求的流量并进行处理转发至上游服务&#xff0c;…

说一说JVM的垃圾回收器

垃圾回收器1.Serial收集器2.parnew收集器3 .parallel Scavenge收集器4.Serial Old5.parallel old收集器6.cms7. G1 收集器串行&#xff1a;指的是垃圾回收器与用户线程交替进行&#xff0c;这意味着在垃圾回收器执行的时候用户线程需要暂停工作 并行&#xff1a;指的是垃圾回收…