让我们进入面向对象的世界(四)

news2024/11/24 12:49:41

文章目录

  • 前言
  • 一. 初始多态
    • 1.1 多态是什么
    • 1.2 多态是怎么工作
    • 1.3多态的向上转型和向下转型
  • 二.多态的好处
  • 三.总结


前言

前面我们讲过了,面向对象继承的特性,下面我们会根据多态来展开讨论,还是用熟悉的方式,让大家去了解这个疯狂的东西。


一. 初始多态

1.1 多态是什么

多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。
听起来你会觉得很奇怪,当我们去调用不同对象的时候,我们会产生不同的行为,举例子来说这里有一个打印机,然后我们打印东西,可以打黑白的,也可以打彩色的,明明同样是打印机,但我们根据不同的状态,调用同一个方法,可能呈现的行为是不一样的。

1.2 多态是怎么工作

说实话哈,如果要看多态是怎么工作的,我们就要从对象的引用和声明,创建对象的方法开始,为什么这么说呢?大家看我下面的操作就知道了。


//这里我声明一个狗对象
Dog mydog =new Dog();

它实际上在做了一个什么样操作呢?看下面的图,你就明白了。

在这里插入图片描述

然后我这里这么写代码,记住我这样写,是因为在多态中,引用和对象可以是不同的类型

Animal animal=new Dog();
//这编译是能够通过的。

在这句代码中,究竟发生了什么呢?现在让我们来看看。
在这里插入图片描述

其实这里就说明了一个问题,就是我们在使用多态时,引用类型是实际对象类的父类


大家如果还是对多态机制懵懵懂懂的,我们直接上来写一个简单的例子,这个例子就是简单的三个类,Animal、Dog、Cat类,就用这个例子,来讲明白多态。


public class Animal {
    String picture;//动物图像的名称
    String food;//动物所吃的食物
    int hunger;//代表饥饿程度的值,根据动物吃了多少来定义
    int boundaries;//动物活动的区域
    double location;//动物活动区域的X与Y的坐标
    public Animal(){

    }
    public Animal(String picture, String food, int hunger, int boundaries, double location) {
        this.picture = picture;
        this.food = food;
        this.hunger = hunger;
        this.boundaries = boundaries;
        this.location = location;
    }

    public void  makeNoise(){
        //动物发出的声音
        System.out.println(picture+"发声音");

    }
    public  void eat(){
        //吃东西
    }
    public void  sleep(){
        //睡眠
    }
    public void roam(){
        //其他的行为
    }
}


public class Cat extends Animal{

    public Cat() {
        super();
    }
    public Cat(String picture, String food, int hunger, int boundaries, double location){
        super(picture,food,hunger,boundaries,location);
    }


    @Override
    public void makeNoise() {
        System.out.println(picture+"喵喵叫");
    }

    @Override
    public void eat() {
        System.out.println(picture+"吃鱼");
    }
}


public class Dog extends Animal{
    public Dog() {
        super();

    }
    public Dog(String picture, String food, int hunger, int boundaries, double location){
        super(picture,food,hunger,boundaries,location);
    }


    @Override
    public void makeNoise() {
        System.out.println(picture+"汪汪叫");
    }

    @Override
    public void eat() {
        System.out.println(picture+"啃骨头");
    }
}

上面就是我们定义好的三个类,我们现在在main方法中进行不同的操作,看看会发生什么。

 Animal animal2=new Dog();
        animal2.picture="旺财";
        animal2.eat();

运行结果:
在这里插入图片描述

实际上,我们去调试的时候,我们去发现这个annimal的引用实际上是指向了dog对象的。
在这里插入图片描述
这里实际上说明了一个观点。
当你声明一个引用变量时,任何对该引用变量类型可通过IS-A测试的对象都可以被赋值给该引用。换句话说,任何extends过声明引用变量类型的对象都可以被赋值给这个引用变量。这样子你就可以做出多态数组这一类的东西。
相信大家对多态的印象又多了了一分,接下来,我们会接触到多态的向上转型和向下转型。

1.3多态的向上转型和向下转型

可能大家对于多态还是非常陌生,我也知道大家很难理解,我这里之所以引入这个东西,大家也不要在意,语法是语法,后面有实际的例子,当大家进行一个综合例子之后,就能慢慢理解多态了。


向上转型
我简单来理解,向上转型就等同于数据类型中的自动类型转换,感觉上是差不多的。

/*
Animal 和 Dog 类
是父与子的关系
*/
Animal aniaml=new Dog();//这里就发生了向上转型。
//语法就是这么简单,没什么复杂度,难得是运用

这里我也举一个实际的例子,让大家体验一下,向上转型的语法

我们有三个类Animal、dog、cat类,类如下:
这里我是把三个类写到一起的,方便给你们观看的。

public class Animal {
    String name;
    String age;
    public void Play(){
        System.out.println(name+"玩耍");
    }
    public void Eat(){
        System.out.println(name+"吃东西");
    }
    public void  sleep(){
        System.out.println(name+"睡觉");
    }
}
public class Dog extends Animal{
    public void Eat(){
        System.out.println(name+"啃骨头");
    }
}

public class Cat extends Animal{

    public void Eat(){
        System.out.println(name+"吃鱼鱼!!");
    }
}

我们接下来要做一个什么事情呢?就是我们使用不同的对象调用,会产生不同的动作。我会用俩种方式,一种是使用多态,一种是不使用多态,去进行。

不使用多态的话,我们就要使用if条件去判断是否是一个东西,然后根据这个不同的对象,去输出行为。

public class Test {
    public static void xingwei1(){
        Cat cat =new Cat();
        cat.name="猜猜";
        Dog dog=new Dog();
        dog.name="旺财";
        String[] animals={"dog","cat"};
        for (String a:animals){
            if (a.equals("dog")){
                dog.eat();
            }else if (a.equals("cat")){
                cat.eat();
            }
        }
    }
    public static void main(String[] args) {
           xingwei1();

    }
}

使用多态的向上转型后,代码稍稍做了一些修改,但也不难理解。

    public static void xingwei2(){
        Cat cat =new Cat();
        cat.name="猜猜";
        Dog dog =new Dog();
        dog.name="旺财";
        Animal[] animal1={cat,dog};//这里就是用了,多态
        for (Animal s:animal1) {
                s.eat();
            
        }
    }
    public static void main(String[] args) {
//           xingwei();
        xingwei2();

    }
}

这里你就可以看出,多态的向上转型,可以让代码变得异常灵活了。


** 向下转型**
我的理解是向下转型跟数据类型的强制类型转换差不多,大家大致来看一看语法机制,你就明白了。

  		Cat cat =new Cat();
        Animal animal=new Dog();
        //此时aniaml是狗,不可能是猫,此时我们就需要向下转型
       cat=(Cat) animal;
		cat.eat();

但向下转型存在一个问题哈,你用常规性的思维思考一下,狗怎么会变成猫呢?这完全就是不符合常理,你不信的话,你运行一下,你就会看到如下警报
在这里插入图片描述
因此,我们有时候,在向下转型的时候,会运用一个关键字,instanof,去判断是否合法

  Cat cat =new Cat();
        Dog dog =new Dog();
        Animal animal = cat;
        //此时aniaml是狗,不可能是猫,此时我们就需要向下转型

        if(animal instanceof Cat){
            cat = (Cat)animal;
            cat.eat();
        }
        if(animal instanceof Dog){
            dog = (Dog)animal;
            dog.eat();
        }

好了好了,同志们,看了这么久的多态以后。我们来进行一个综合例子,去观察观察,多态的好处。

二.多态的好处

大家都知道打印图形的例子吧,我们操作一个对象进行不同的行为。还是来两种方式,一种用多态的方式和一种用多态的方式,

2.1不用多态的方式

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("画圆!");
    }
}

public class TestMain(){
public static void drawMap() {
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Flower flower = new Flower();
        //cycle  rect  cycle  rect  flower
        String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};
        for (String s : shapes) {
            if(s.equals("cycle")) {
                cycle.draw();
            }else if(s.equals("rect")) {
                rect.draw();
          
        }
    }

public static void main(String[] args) {	
	drawMap();
}
}

使用多态的版本

 public static void drawMap() {
        Shape rect = new Rect();
        Shape cycle = new Cycle();
        Shape flower = new Flower();

        Shape[] shapes = {cycle,rect,cycle,rect};
        //int[] array = {1,2,3,4};
        for(Shape shape : shapes) {
            shape.draw();
        }
    }
    public static void main(String[] args) {	
	drawMap();
}
    

看了上面的俩个例子香型你们已经大概理解多态的机制。

三.总结

通过多态,你就可以编写出引进新型子类时也不必修改的程序。
这可能,有些简短了,但事实就是这样。
又到了,跟大家说再见的时候了,下一次我们将带大家深入多态,了解抽象类和接口

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

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

相关文章

软考证书具体用途--详细介绍

拿到软考证书的前提是对你自己今后的职业发展有帮助,用得到才能对你而言发挥它最大的好处。 软考证书的具体用途: 1.纳入我国高校人才培养和教学体系 目前,软考已经被纳入高校人才培养和教学体系。在很多高校中,软考纳入学分&a…

设置渐变边框色

如上图所示,需设置渐变边框色,左右边框颜色固定,上边框从左到右开始渐变,下边框从右到左开始渐变。 思考了很久,如果看作是一个div,则需要用到 border-image属性设置渐变色。也可以看作是两个div&#xff0…

北大学者发现,经常喝牛奶,增加中国人肝癌和乳腺癌风险

牛奶是生活中常见的饮品。牛奶含有丰富的蛋白质,钙元素等多种营养成分,能为人体提供充足的蛋白质和钙,增强人体的体质,提高免疫力。然而,无论是什么,物极必反,过量饮用也会对身体产生不利的影响…

2022Flink大数据比赛项目-焦点科技大数据编程大赛

文章目录0.数据获取1.需求概要2.数据标准2.1.输入数据格式2.2.输出数据格式2.3.数据主键及关系3.表详细1.order_info2.bill_info3.bill_item4.ord_pay5.ord_pay_log6.pay_method7.pay_bank_card4.开发工具、语言版本、工具版本5.赛题解答数据分流任务1任务2任务3小结附录0.数据…

股票详情接口是怎样开发的?

一般情况下,在量化市场中,投资者使用的辅助炒股软件就包括很多数据接口,特别是股票详情接口系统更为可见,不过在使用之前,也是需要提前了解清楚它的开发原理,以及使用规则等,那么它是怎样开发出…

麦芽糖-链霉亲和素maltose-Streptavidins链霉亲和素-PEG-麦芽糖

麦芽糖-链霉亲和素maltose-Streptavidins链霉亲和素-PEG-麦芽糖 中文名称:麦芽糖-链霉亲和素 英文名称:maltose-Streptavidins 别称:链霉亲和素修饰麦芽糖,链霉亲和素-麦芽糖 提供PEG接枝修饰麦芽糖,麦芽糖-聚…

易观千帆 | 2022年10月银行APP月活跃用户规模盘点

易观分析:易观千帆数据显示,10月手机银行服务应用活跃人数52285.79万,环比下降3.52%。手机银行服务应用月活规模经历了连续5个月的持续增长后,10月出现下降。 10月城商行手机银行服务应用活跃人数3565.56万,环比下降2…

线程的概念和创建【javaee初阶】

目录 一、认识线程 二、多线程程序 2.1 实现Java多线程程序 方法1 继承 Thread ,重写run 方法2 实现 Runnable 接口 方法3 匿名内部类创建 Thread 子类对象 方法4 匿名内部类创建 Runnable 子类对象 方法5 lambda 表达式创建 Runnable 子类对象 三、多线程的…

Kamiya丨Kamiya艾美捷小鼠高敏CRP ELISA说明书

Kamiya艾美捷小鼠高敏CRP ELISA预期用途: 小鼠高敏CRP ELISA是一种高灵敏度的双位点酶联免疫分析(ELISA)定量测定小鼠生物样品中的C-反应蛋白(CRP)。仅供研究使用。 引言 急性期蛋白质是血浆蛋白质,其在感…

交互作用的深入剖析

1.原理说明 交互作用(Interaction effect)指两个或多个因素(比如A因素和B因素)对于某项(比如身高)的影响时,A因素和B因素各个水平之间是否存在着相互作用关系。比如A因素为性别,B因素为区域,男…

Springboot+vue+java幼儿园管理系统

开发语言:Java 框架:springboot 前端框架:vue.js JDK版本:JDK1.8 服务器:tomcat8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea 目 录 第一章 绪 论 1 1.1背景及意义 1…

Android Qcom Sensor架构学习

Android Sensor Brief Flow Android Sensor Specific Flow ADSP SSC ADSP.VT.5.4.1/adsp_proc/ssc_api/pb/ ADSP.VT.5.4.1/adsp_proc/ssc/sensors ADSP.VT.5.4.1/adsp_proc/ssc/frameworksADSP Framework初始化的时候首先通过load image并初始化的静态加载方式register_static…

数据结构期末刷题

写在前面 此篇文章是在网络上搜集的题目,每一题都可能出现错误,如果各位大佬发现了错误,请在评论区回复一下,看到了就会改 树 根据遍历序列,画树,求另外一种遍历序列 以下中序遍历简称为中序&#xff0…

电路设计 > eMMC应用和PCB layout布局布线参考设计

目录 eMMC介绍 eMMC信号大体介绍 EMMC4.5和5.0封装和兼容性对比 EMMC5.0和5.1封装和兼容性对比 PCB Layout建议 PCB layout参考设计 参考设计1 参考设计2 参考设计3 参考设计4 参考设计5​​​​​​​ eMMC介绍 主要针对现在主流的eMMC5.0以及以上版本。 eMMC信号…

centos 7 安装node-red

一、安装nodejs https://nodejs.org/en/download/ 将其上传到服务器/usr/local/src目录下 下载之后是xz文件,解压xz文件 xz -d node-v16.18.1-linux-x64.tar.xz 解压之后会多一个tar文件,解压tar文件 tar -vxf node-v16.18.1-linux-x64.tar mkdir …

Navicat远程连接MySQL服务器

文章目录一、准备二、配置Navicat允许远程连接MySQL数据库1、使用Navicat直接连接MySQL2、使用 Navicat 通过 SSH 远程登录后再本地方式连接 MySQL3、查看连接为什么使用ssh登录1.便捷性Navicat:数据库可视化工具 一、准备 一台开启 SSH 登录的 Ubuntu 服务器 或 已开启远程登…

PyTorch学习笔记-神经网络Torch.NN基本骨架的使用及卷积原理

1. torch.nn.Module介绍 torch.nn 能够帮助我们更优雅地训练神经网络,使神经网络代码更加简洁和灵活。官方文档:Torch.NN。 在文档中可以看到第一块内容叫做 Container(容器),这就相当于神经网络的骨架,C…

U2Net——U-Net套U-Net——套娃式图像分割算法

U2Net1 相关参考2 U2−NetU^2-NetU2−Net 网络结构3 网络代码和测试1 相关参考 论文名称: U2-Net: Goging Deeper with Nested U-Structure for Salient Object Detetion 论文地址: https://arxiv.org/abs/2005.09007 官方源码: https://git…

机器视觉_工业相机及相关配件选型

文章目录工业相机一、 概述二、 相机参数1. 传感器芯片1.1. CCD&CMOS1.2. CCD1.3. CMOS1.4. 靶面1.5. 传感器芯片选型2. 黑白or彩色3. 帧数⭐4. 接口类型4.1. POE供电三、相关硬件1. 镜头1.1. 焦距2. 光源3. 控制器4. 工控机5. 线缆6. 交换机四、参考工业相机 一、 概述 …

基于FPGA的呼叫设备verilog开发

欢迎订阅《FPGA学习入门100例教程》、《MATLAB学习入门100例教程》 目录 一、理论基础 二、核心程序 三、测试结果 一、理论基础 随着集成电路技术的发展,电子设计自动化(EDA)逐渐成为重要的设计手段,已经广泛应用于模拟与数字…