首页 > 编程语言 >Java面向对象---多态

Java面向对象---多态

时间:2025-01-15 16:32:38浏览次数:3  
标签:Java 子类 多态 Cat --- 类型 Dog 父类

1 多态的形式

多态是继封装、继承之后,面向对象的第三大特性。

多态是出现在继承或者实现关系中的

多态体现的格式

父类类型 变量名 = new 子类/实现类构造器;
变量名.方法名();

多态的前提:有继承关系,子类对象是可以赋值给父类类型的变量。例如Animal是一个动物类型,而Cat是一个猫类型。Cat继承了Animal,Cat对象也是Animal类型,自然可以赋值给父类类型的变量。

2 多态的使用场景

如果没有多态,在下图中register方法只能传递学生对象,其他的Teacher和administrator对象是无法传递给register方法方法的,在这种情况下,只能定义三个不同的register方法分别接收学生,老师和管理员。
在这里插入图片描述
有了多态之后,方法的形参就可以定义为共同的父类Person。

要注意的是:

  • 当一个方法的形参是一个类,我们可以传递这个类所有的子类对象。
  • 当一个方法的形参是一个接口,我们可以传递这个接口所有的实现类对象(后面会学)。
  • 而且多态还可以根据传递的不同对象来调用不同类中的方法。
    在这里插入图片描述

3 多态的定义和前提

多态: 是指同一行为,具有多个不同表现形式。

从上面案例可以看出,Cat和Dog都是动物,都是吃这一行为,但是出现的效果(表现形式)是不一样的。

前提【重点】

  1. 有继承或者实现关系

  2. 方法的重写【意义体现:不重写,无意义】

  3. 父类引用指向子类对象【格式体现】

    父类类型:指子类对象继承的父类类型,或者实现的父接口类型。

4 多态的运行特点

调用成员变量时:编译看左边,运行看左边

调用成员方法时:编译看左边,运行看右边

代码示例:

Fu f = new Zi();
//编译看左边的父类中有没有name这个属性,没有就报错
//在实际运行的时候,把父类name属性的值打印出来
System.out.println(f.name);
//编译看左边的父类中有没有show这个方法,没有就报错
//在实际运行的时候,运行的是子类中的show方法
f.show();

5 多态的弊端

我们已经知道多态编译阶段是看左边父类类型的,如果子类有些独有的功能,此时多态的写法就无法访问子类独有功能了

class Animal{
    public  void eat(){
        System.out.println("动物吃东西!")
    }
}
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃鱼");  
    }  
   
    public void catchMouse() {  
        System.out.println("抓老鼠");  
    }  
}  

class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨头");  
    }  
}

class Test{
    public static void main(String[] args){
        Animal a = new Cat();
        a.eat();
        a.catchMouse();//编译报错,编译看左边,Animal没有这个方法
    }
}

6 引用类型转换

6.1 为什么要转型

多态的写法就无法访问子类独有功能了。

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子类特有的方法,必须做向下转型。

回顾基本数据类型转换

  • 自动转换: 范围小的赋值给范围大的.自动完成:double d = 5;
  • 强制转换: 范围大的赋值给范围小的,强制转换:int i = (int)3.14

​ 多态的转型分为向上转型(自动转换)与向下转型(强制转换)两种。

6.2 向上转型(自动转换)

  • 向上转型:多态本身是子类类型向父类类型向上转换(自动转换)的过程,这个过程是默认的。
    当父类引用指向一个子类对象时,便是向上转型。
    使用格式:
  父类类型  变量名 = new 子类类型();
如:Animal a = new Cat();

6.3 向下转型(强制转换)

  • 向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的。
    一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。

使用格式:

子类类型 变量名 = (子类类型) 父类变量名;
如:Aniaml a = new Cat();
   Cat c =(Cat) a;  

6.4 转型的异常

转型的过程中,一不小心就会遇到这样的问题,请看如下代码:

public class Test {
    public static void main(String[] args) {
        // 向上转型  
        Animal a = new Cat();  
        a.eat();               // 调用的是 Cat 的 eat

        // 向下转型  
        Dog d = (Dog)a;       
        d.watchHouse();        // 调用的是 Dog 的 watchHouse 【运行报错】
    }  
}

这段代码可以通过编译,但是运行时,却报出了 ClassCastException ,类型转换异常!这是因为,明明创建了Cat类型对象,运行时,当然不能转换成Dog对象的。

6.5 instanceof关键字

为了避免ClassCastException的发生,Java提供了 instanceof 关键字,给引用变量做类型的校验,格式如下:

变量名 instanceof 数据类型
如果变量属于该数据类型或者其子类类型,返回true。
如果变量不属于该数据类型或者其子类类型,返回false。

public class Test {
    public static void main(String[] args) {
        // 向上转型  
        Animal a = new Cat();  
        a.eat();               // 调用的是 Cat 的 eat

        // 向下转型  
        if (a instanceof Cat){
            Cat c = (Cat)a;       
            c.catchMouse();        // 调用的是 Cat 的 catchMouse
        } else if (a instanceof Dog){
            Dog d = (Dog)a;       
            d.watchHouse();       // 调用的是 Dog 的 watchHouse
        }
    }  
}

6.6 instanceof新特性

JDK14的时候提出了新特性,把判断和强转合并成了一行

//新特性
//先判断a是否为Dog类型,如果是,则强转成Dog类型,转换之后变量名为d
//如果不是,则不强转,结果直接是false
if(a instanceof Dog d){
    d.lookHome();
}else if(a instanceof Cat c){
    c.catchMouse();
}else{
    System.out.println("没有这个类型,无法转换");
}

标签:Java,子类,多态,Cat,---,类型,Dog,父类
From: https://blog.csdn.net/qq_48763502/article/details/145131759

相关文章

  • 【开源免费】基于SpringBoot+Vue.JS在线课程管理系统(JAVA毕业设计)
    本文项目编号T137,文末自助获取源码\color{red}{T137,文末自助获取源码}......
  • 【开源免费】基于SpringBoot+Vue.JS社团管理系统(JAVA毕业设计)
    本文项目编号T136,文末自助获取源码\color{red}{T136,文末自助获取源码}......
  • 【开源免费】基于SpringBoot+Vue.JS企业OA管理系统(JAVA毕业设计)
    本文项目编号T135,文末自助获取源码\color{red}{T135,文末自助获取源码}......
  • 数学建模学习-整数规划(Integer Programming)教程(3)
    数学建模学习-整数规划(IntegerProgramming)教程(3)写在最前注意本文的相关代码及例子为同学们提供参考,借鉴相关结构,在这里举一些通俗易懂的例子,方便同学们根据实际情况修改代码,很多同学私信反映能否添加一些可视化,这里每篇教程都尽可能增加一些可视化方便同学理解,但具体......
  • HackMyVM-XMAS靶机的测试报告
    目录一、测试环境1、系统环境2、使用工具/软件二、测试目的三、操作过程1、信息搜集2、Getshell3、提权四、结论一、测试环境1、系统环境渗透机:kali2021.1(192.168.159.127)靶 机:ubuntu23.04(192.168.159.158)注意事项:①该类型靶场只能在virtualBox上搭建......
  • L1-002 打印沙漏
    题目:L1-002打印沙漏-团体程序设计天梯赛-练习集题目要求本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印:*****************所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小......
  • Java的概述
    Java的概述Java语言的特点简单性 解释性面向对象高性能面向对象 高性能分布式处理 多线程健壮性 动态结构中立 安全性开源跨平台什么是跨平台性?通过Java语言编写的应用程序在不同的系统平台上都可以运行。原理是什么?只要在需要运行java应用程序的操作系统上,先......
  • X00456-基于金融知识图谱的实体检索系统完整代码文件
    本系统整合了Yago和Dbpedia公开数据集,基于纳斯达克500强公司数据进行抽取,构建了金融领域的知识图谱。系统采用Vue、Django和MySQL技术栈,提供交互式可视化界面,支持实体检索、实体信息查看、相关实体推荐及实体相关新闻等功能。通过这些功能,用户能够更加直观地探索知识图谱,并迅速获......
  • dbt Semantic Layer 详细教程-6 :指标(metrics)配置规范及示例
    前面几篇博文介绍了语义模型及实体、维度和度量规范及示例,一旦创建了语义模型,就该开始添加度量了。可以在与语义模型相同的YAML文件中定义度量,也可以将度量拆分为单独的YAML文件,放入任何其他子目录中(前提是这些子目录也位于相同的dbt项目repo中)。本文介绍指标配置规范,并针......
  • 【前端】自学基础算法 -- 25.动态规划-01背包问题
    动态规划-01背包问题简介动态规划(DynamicProgramming,简称DP)是一种解决复杂问题的方法,它将问题分解为更小、更简单的子问题,并存储这些子问题的解,以避免重复计算。动态规划通常用于优化问题,如求最大值、最小值或计数问题。动态规划的基本思想是将大问题分解为小问题,并从......