java第二十五课 —— 多态

多态

传统的方法带来的问题是什么?如何解决?问题是:代码的复用性不高,而且不利于代码维护。

未使用多态时候的例子:

Poly01.java:

package com.hspedu.poly_;

public class Poly01 {
    public static void main(String[] args) {
        Master master = new Master("Tom");
        Dog dog = new Dog("旺旺");
        Bone bone = new Bone("大棒骨");
        Cat cat = new Cat("喵喵");
        Fish fish = new Fish("黄花鱼");
        master.feed(dog, bone);
        master.feed(cat, fish);

    }
}

Master.java:

package com.hspedu.poly_;

public class Poly01 {
    public static void main(String[] args) {
        Master master = new Master("Tom");
        Dog dog = new Dog("旺旺");
        Bone bone = new Bone("大棒骨");
        Cat cat = new Cat("喵喵");
        Fish fish = new Fish("黄花鱼");
        master.feed(dog, bone);
        master.feed(cat, fish);

    }package com.hspedu.poly_;

public class Master {
    private String name;

    public Master(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //主人给小狗吃骨头
    public void feed(Dog dog, Bone bone){
        System.out.println("主人 " + name + " 给 " + dog.getName() + " 吃 " + bone.getName());
    }
    //主人给小猫吃黄花鱼
    public void feed(Cat cat, Fish fish){
        System.out.println("主人 " + name + " 给 " + cat.getName() + " 吃 " + fish.getName());
    }
    //如果动物很多,食物很多
    // ===> feed 方法很多,不利于管理和维护
}

Animal.java:

package com.hspedu.poly_;

public class Animal {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Dog.java:

package com.hspedu.poly_;

public class Dog extends Animal{
    public Dog(String name) {
        super(name);
    }
}

Cat.java:

package com.hspedu.poly_;

public class Cat extends Animal{
    public Cat(String name) {
        super(name);
    }
}

Food.java:

package com.hspedu.poly_;

public class Food {
    private String name;
    public Food(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Bone.java:

package com.hspedu.poly_;

public class Bone extends Food{
    public Bone(String name) {
        super(name);
    }
}

Fish.java:

package com.hspedu.poly_;

public class Fish extends Food {
    public Fish(String name) {
        super(name);
    }
}

基本介绍

方法对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的

方法的多态

重写和重载就体现多态。

对象的多态

  1. 一个对象的编译类型和运行类型可以不一致。
  2. 编译类型在定义对象时,就确定了,不能改变。
  3. 运行类型是可以变化的。
  4. 编译类型看定义时 = 号的左边,运行类型看 = 号的右边。

对象的多态案例:

Animal animal = new Dog(); animal 编译类型是 Animal,运行类型 Dog。
animal = new Cat(); 编译类型仍然是 Animal,animal 的运行类型变成了 Cat。

PolyObject.java:

package com.hspedu.poly_.objpoly_;

public class PolyObject {
    public static void main(String[] args) {
        //体验对象多态的特点
        Animal animal = new Dog();//animal 编译类型就是 Animal,运行类型 Dog
        //因为运行时 ,执行到改行时,animal 运行类型是 Dog,所以 cry 就是 Dog 的 cry
        animal.cry();//小狗汪汪叫

        //animal 编译类型 Animal,运行类型就是 Cat
        animal = new Cat();
        animal.cry();//小猫喵喵叫
    }
}

Animal.java:

package com.hspedu.poly_.objpoly_;

public class Animal {
    public void cry(){
        System.out.println("Animal cry() 动物在叫...");
    }
}

Dog.java:

package com.hspedu.poly_.objpoly_;

public class Dog extends Animal{
    public void cry() {
        System.out.println("Dog cry() 小狗汪汪叫...");
    }
}

Cat.java:

package com.hspedu.poly_.objpoly_;

public class Cat extends Animal{
    public void cry() {
        System.out.println("Cat cry() 小猫喵喵叫...");
    }
}

使用多态后文章开头例子中的 Master.java 可以修改为:

Master.java:

package com.hspedu.poly_;

public class Master {
    private String name;

    public Master(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    // 使用多态机制,可以统一的管理主人喂食的问题
    // animal 编译类型是 Animal,可以指向(接收) Animal 子类的对象
    // food 编译类型是 Food 可以指向(接收) Food 子类的对象
    public void feed(Animal animal, Food food){
        System.out.println("主人 " + name + " 给 " + animal.getName() + " 吃 " + food.getName());
    }
}

多态的注意事项和细节

  1. 多态的前提是:两个对象(类)存在继承关系。

  2. 多态的 向上转型

    • 本质:父类的引用指向了子类的对象。

    • 语法:父类类型 引用名 = new 子类类型();

    • 特点:编译类型看左边,运行类型看右边。

      可以调用父类中的所有成员(需遵守访问权限)

      不能调用子类中特有成员;因为在编译阶段,能调用哪些成员,是由编译类型来决定的。

      最终运行效果看子类的具体实现! 即调用方法时,按照从子类开始查找方法,然后调用。

例子:

PolyDetail.java:

package com.hspedu.poly_.detail_;

public class PolyDetail {
    public static void main(String[] args) {
        //向上转型:父类的引用指向了子类的对象
        //语法:父类类型 引用名 = new 子类类型();
        Animal animal = new Cat();
        Object obj = new Cat();//可以吗? 可以 0bject 也是 Cat 的父类

        //可以调用父类中的所有成员(需遵守访问权限)
        //animal.catchMouse();错误

        //最终运行效果看子类的具体实现!
        animal.eat();//猫吃鱼
        animal.run();//跑
        animal.show();//Hello, 你好
        animal.sleep();//睡
    }
}

Animal.java:

package com.hspedu.poly_.detail_;

public class Animal {
    String name = "动物";
    int age = 10;
    public void sleep(){
        System.out.println("睡");
    }
    public void run(){
        System.out.println("跑");
    }
    public void eat(){
        System.out.println("吃");
    }
    public void show(){
        System.out.println("Hello, 你好");
    }
}

Cat.java:

package com.hspedu.poly_.detail_;

public class Cat extends Animal{
    public void eat(){//方法重写
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){//Cat()特有的方法
        System.out.println("猫抓老鼠");
    }
}
  1. 多态的 向下转型
    • 语法:子类类型 引用名 = (子类类型) 父类引用;
    • 只能强转父类的引用,不能强转父类的对象。
    • 要求父类的引用必须指向的是当前目标类型的对象。
    • 当向下转型后,可以调用子类类型中所有的成员。

PolyDetail.java:

package com.hspedu.poly_.detail_;

public class PolyDetail {
    public static void main(String[] args) {
        //向上转型:父类的引用指向了子类的对象
        //语法:父类类型 引用名 = new 子类类型();
        Animal animal = new Cat();

        //希望可以调用Cat的 catchMouse 方法
        //多态的向下转型
        //语法:子类类型 引用名=(子类类型)父类引用;
        //cat 的编译类型 Cat,运行类型是 Cat
        Cat cat = (Cat)animal;
        cat.catchMouse();

        //要求父类的引用必须指向的是当前目标类型的对象。
        //Dog dog = (Dog)animal; 错误。父类的引用指向的是 Cat 而不是 Dog
    }
}
  1. 属性没有重写之说!属性的值看编译类型。

PolyDetail02.java:

package com.hspedu.poly_.detail_;

import com.hspedu.super_.B;

public class PolyDetail02 {
    public static void main(String[] args) {
        //属性没有重写之说!属性的值看编译类型。
        Base base = new Sub();//向上转型
        System.out.println(base.count);//10,看编译类型。
    }
}
class Base{
    public int count = 10;
}
class Sub extends Base{
    public int count = 20;
}
  1. instanceof 比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型。

练习题

  1. 请说出下面的每条语言,哪些是正确的,哪些是错误的,为什么?

在这里插入图片描述

public class PolyExercise01{
public static void main(String[] args) {
    double d = 13.4;//ok
    long l = (long)d;//ok
    System.out.println(l);//13
    int in = 5;//ok
    boolean b =(boolean)in;//不对,boolean 类型不参与转化
    Object obj = "Hello";//ok,向上转型
    String objstr = (String)obj;//ok,向下转型
    System.out.println(objStr);//Hello
	Object objPri = new Integer(5);//ok,向上转型
    String str = (String)objPri;//不对,父类的引用指向的是 Integer 而不是 String
    Integer str1 =(Integer)objPri;//ok,向下转型
}}
  1. 题目:

在这里插入图片描述

public class PolyExercise02{
    public static void main(String[] args){
        Sub s = new Sub();
        System.out.println(s.count);//20
        s.display();//20
        Base b = s;//向上转型
        System.out.println(b == s);//true,两个对象比较的是地址,都指向了同一个Sub对象。
        System.out.println(b.count);//10
        b.display();//20
}}
class Base{//父类
    int count = 10;
    public void display(){
        System.out.println(this.count);
}
class Sub extends Base{//子类
    int count = 20;
    public void display(){
        System.out.println(this.count);
}

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

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

相关文章

【CT】LeetCode手撕—236. 二叉树的最近公共祖先

目录 题目1- 思路2- 实现⭐236. 二叉树的最近公共祖先——题解思路 3- ACM实现 题目 原题连接:236. 二叉树的最近公共祖先 1- 思路 模式识别 模式1:二叉树最近公共祖先 ——> 递归 判断 递归思路,分情况判断: 1.参数及返…

Linux系统OpenSSH_9.7p1升级详细步骤

版本说明 当前内核版本如下 当前操作系统版本如下 当前OpenSSH版本和OpenSSL版本如下 升级说明 openssh依赖于openssl和zlib,而openssl依赖于zlib,所以我们要先安装zlib,然后是openssl,最后是openssh。zlib-1.3.1下载地址&#…

Folly,一个强大的C++库

目录 1.引言 2.Folly库的特点 3.Folly库的应用场景 4.示例代码 5.总结 1.引言 Folly 是Facebook开发的一个开源、无许可(Apache 2.0)的现代C库,旨在提升性能和简化编写复杂任务的工作流程。它包含了一系列用于系统级编程的工具&#xff…

白蚁监测装置:支持北斗定位

TH-BY2白蚁监测控制管理系统原理 采用白蚁喜欢吃的食物做诱饵,吸引白蚁取食,取食过程中触动报警装置。报警装置发出信号,通过物联网传输到监控系统,经过数据处理,监测结果呈现给用户。用户通知白蚁防治专业人员&#x…

618数码好物有哪些?热门榜单强势出炉

大家好!随着6.18购物狂欢节的来临,我可以明白在面对非常吸引人的商品时,“选择困难症”就上来了。因此,为了帮助大家在这场购物盛事中有方向,我特意结合个人使用体验和市场研究,为大家筛选了几件既具有超高…

CSP-J/S初赛01 计算机概述和计算机硬件系统

第1节 计算机概述 1.1 计算机的发展 代别 年代 逻辑(电子)元件 第一代 1946-1958 真空电子管 第二代 1959-1964 晶体管 第三代 1965-1970 集成电路 第四代 1971-至今 大规模、超大规模集成电…

Einops 张量操作快速入门

张量,即多维数组,是现代机器学习框架的支柱。操纵这些张量可能会变得冗长且难以阅读,尤其是在处理高维数据时。Einops 使用简洁的符号简化了这些操作。 Einops (Einstein-Inspired Notation for operations)&#xff…

HTTP 415错误状态码

HTTP 415错误状态码是指"Unsupported Media Type"(不支持的媒体类型)。这通常发生在客户端向服务器发送请求时,请求中包含的媒体类型(例如Content-Type头部)不被服务器支持或识别的情况下。 解决方法&#…

Erpnext安装

Erpnext安装 环境要求 Ubuntu 23.04 x86_64 Python 3.10.12 pip 23.0.1 node v18.16.0 npm 9.5.1 yarn 1.22.22 MariaDB 10.11.2 Redis 7.0.8 wkhtmltox 0.12.6.1 bench 5.22.6环境安装 Reids 安装 // 安装7.0.8 也可不指定版本 直接执行 sudo apt install redis-server s…

XX集团网上客户管理系统投标书技术部分(358页WORD)

方案介绍:针对客户不断增加的便民查询,业务受理等实际需求,我们将积极整合国内外人才、技术、产品资源,打造XX最便捷的网上处理平台。在平台建设和运营基础上,持续探索各种创新模式,发展多种有针对性的衍生…

攻防演练“轻装上阵” | 亚信安全信舱ForCloud 打造全栈防护新策略

网络世界攻防实战中,攻击风险已经从代码到云横跨全栈技术点,你准备好了吗 云服务器,攻击众矢之的 2022年超过38万个Kubernetes API服务器暴露公网,成为攻击者目标。云服务器,尤其是开源设施,一直以来不仅是…

拐点 万维钢电子书(拐点万维钢下载在线阅读)

本文节选自《拐点万维钢》在线阅读 医院急诊室有个特别常见的状况是病人胸口痛。对这种情 况,医生必须判断是不是心脏病,是心脏病就得赶紧处置。但问题 是,急诊医生并没有很好的诊断方法。 通常的做法是搞个正式的检查,而心脏病检…

碳课堂 | 手把手教你申报CBAM

CBAM全称为 Carbon Border Adjustment Mechanism,也被称作“碳关税”或“碳边境调节机制”,是指在实施国内严格气候政策的基础上,要求进口或出口的高碳产品缴纳或退还相应的税费或碳配额。目前,由于欧盟碳边境调节机制是全球第一个…

示例:WPF中在没有MouseDoubleClick的控件中如何识别双击

一、目的&#xff1a;由于MouseDoubleClick控件是在Control中实现&#xff0c;那么在底层控件如Grid中想要类似功能如何实现&#xff0c;这里通过MouseDown的事MouseButtonEventArgs参数去实现 二、实现 定义Grid并注册Grid的MouseDown事件 <Grid Background"Transpa…

Ubuntu,Centos,Linux服务器安装Mellanox MCX653105A IB网卡HCA卡驱动

Mellanox 官方驱动下载地址 https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ 选择对应操作系统 官方链接速度比较慢&#xff0c;推荐个友商的下载地址 https://support.xfusion.com/support/#/zh/rack-servers/2288h-v5-pid-21872244/software …

对 PLC AC 模块的 TRIAC 输出进行故障排除

在大多数离散 PLC 系统中&#xff0c;排除输出设备故障的过程相当简单。如果输出端正常工作&#xff0c;则在“关闭”时应测量 0 V&#xff0c;在“开启”时应测量满源电压。对于数字和继电器输出&#xff0c;情况确实如此。对于由 TRIAC 驱动的 AC 输出也应如此&#xff0c;但…

C++通过VS2022使用Conan2.0安装fmt库实现控制台彩色打印

Conan是一个开源的C/C包管理器&#xff0c;用于管理和构建C/C项目的依赖关系。它允许开发人员轻松地集成第三方库、工具和资源到他们的项目中&#xff0c;并管理这些依赖项的版本、构建选项和配置。 Conan官方提供了对应的VS2022扩展插件&#xff0c;通过这个插件再搭配VS2022…

如何正确操作工业高温烤箱

高温烤箱广泛应用于陶瓷、丝印、汽车配件、电子、机电、通讯、化工、器材、印刷、制药、工业、橡胶、油漆、食品之烘烤、水份干燥、预热等用途。那么要想工业高温烤箱在使用的过程中能够正常运行&#xff0c;那么正确的操作是必不可少的&#xff0c; 1、防止触电&#xff1a;高…

电脑文件防泄密软件——天锐绿盾 - 中科数安—— 哪个好

在选择电脑文件防泄密软件时&#xff0c;天锐绿盾和中科数安都是值得考虑的选项。以下是对这两款软件的详细比较&#xff1a; www.drhchina.com PC地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 功能全面性&#xff1a; 天锐…

具身智能的视觉-语言-动作模型综合综述论文

近期arXiv公开了关于具身智能&#xff08;Embodied AI&#xff09;中的视觉-语言-动作模型&#xff08;Vision-Language-Action Models&#xff0c;简称VLAs&#xff09;的综合综述论文。介绍了VLAs的概念&#xff0c;它们是为了处理多模态输入而设计的模型&#xff0c;包括视觉…