面向对象------多态

news2024/10/7 12:18:59

1.多态的定义

通俗来说,当同一种行为或者事情发生在不同的对象上,这些行为或者事情最终得到的结果不同

注意:多态要发生在继承的基础上。

例如:彩色打印机和黑白打印机。

彩色打印机和黑白打印机是不同的对象,但打印(行为)这件事分别发生在它们身上的时候,彩色打印机打印的是彩色的,而黑白打印机最终打印的结果却是黑白色的。

9d2c6dfbc7b140c69b09ee67f3d2d610.jpeg

对应到Java中就是相同的方法对应到不同的对象中有不同的结果。

 2.多态的使用

2.1 向上转型

向上转型发生在继承的基础上,所谓向上转型,就是由子类类型向父类类型转换。向上转型的方式由3中,分别为:直接赋值、方法的传参和方法的返回值形式。

cd27b6ff42c54f478357c0f945739ffd.png

1.直接传参

class Animal{
    
}
class Dog extends Animal{
    
}
public class Test {
    public static void main(String[] args) {
        //直接赋值,发生向上转型
        Animal animal=new Dog();
    }
}

2. 方法的传参

class Animal{

}
class Dog extends Animal{

}
public class Test {
    public static void func(Animal animal){
        
    }
    public static void main(String[] args) {
        Dog dog=new Dog();
        //方法的传参实现向上转型
        func(dog);
    }
}

3.方法的返回值

class Animal{

}
class Dog extends Animal{

}
public class Test {
    public static Animal func(){
        Dog dog=new Dog();
        return dog;
    }
    public static void main(String[] args) {
        Animal animal=func();   
    }
}

4 向上转型的缺点

当我们进行了向上转型,我们就不能通过父类的引用(转型之后的引用)去访问子类特有的属性或者方法。 

class Dog extends Animal{
    public Dog(String name,int age){
        super(name, age);
    }
    public void bark(){
        System.out.println(this.name+"在汪汪叫");
    }
}
class Animal{
    public String name;
    public int age;
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal=new Dog("旺财",18);
        animal.bark();
        
    }
}

运行以上代码会报错

3a35aad63445466885f9c1362e88f5fe.png

 2.2 动态绑定

动态绑定是理解多态的基础。

 1.方法的重写

当子类和父类中有一个方法名字一样,参数列表一样和返回值类型一样,但是方法内不得具体实现不一样,则子类对应的方法构成了方法的重写。

class Dog extends Animal{
    public Dog(String name,int age){
        super(name, age);
    }
    @Override  //编译器中方法重写的默认注释
    public void eat() {
        System.out.println(this.name+"在吃狗粮");
    }
}
class Animal{
    public String name;
    public int age;
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void eat(){
        System.out.println(this.name+"在吃饭");
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal=new Dog("旺财",18);
    }
}

576d89fe0853486e98df4213b8c9be63.png

如上图,红框框里面就是构成重写的部分。

2.方法重写的注意事项

1.重写的方法不能是一个静态的方法(被static修饰的方法)。

28c19be6474e4253a98792d78ccb6458.png

2.被final修饰的方法无法被重写

f62da0c70ea540acabba5dd3c82d2a38.png

3.如果子类重写父类的方法时,子类重写方法时的访问权限要大于等于父类方法的权限。

                                    访问权限大小比较
                          public>protected>default>private

bb77810d585141edb5bb2f574fc883d7.png

如图,因为父类要被重写的方法得访问权限为public,而子类中重写的方法的访问权限为private,所以运行代码时,编译器会报错。

4.父类中被private修饰的方法无法被重写

1b6abd7d39a849839ceeb30887da433e.png

5.重写的方法的返回值类型可以不相同,但是返回值类型必须构成父子类的关系。

b86f870320124880b8e861f5bc099294.png

                         

3. 方法的重写和重载的区别

                         重载                      重写
   参数列表中的数据类型,顺序和个priv数可以不一样 参数列表中的数据类型,顺序和个数必须一样
   返回值的类型不一样  返回值类型必须一样
   方法名必须一样   方法名必须一样

4.动态绑定

当运行代码时,我们通过父类的引用去调用在子类和父类中重写的方法,结果实际调用了子类的方法,这种情况就被称为动态绑定。

 代码演示

class Dog extends Animal{
    public Dog(String name,int age){
        super(name, age);
    }
    @Override  //编译器中方法重写的默认注释
    public void eat() {
        System.out.println(this.name+"在吃狗粮");
    }
}
class Animal{
    public String name;
    public int age;
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void eat(){
        System.out.println(this.name+"在吃饭");
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal=new Dog("旺财",18);
        animal.eat();
    }
}

运行代码

3131275c2b1940e5a641801a54ebc4f8.png

通过上面代码,我们发现,当我们完成了向上转型之后,我们通过父类的引用去调用重写的方法时,程序在编译时,调用的确实是父类的eat( )方法。但是由于动态绑定,最终我们看到的是Dog类中的eat( )方法。

 2.3 向下转型

向下转型也是发生在继承的继承的基础上,向下转型就是父类向子类转换。

019109a214b24964aa6670dc6a75a062.png

 1.向下转型的优点

通过向下转型,我们就可以访问子类中特有的属性和方法。

代码演示

class Dog extends Animal{
    public Dog(String name,int age){
        super(name, age);
    }
    @Override  //编译器中方法重写的默认注释
    public void eat() {
        System.out.println(this.name+"在吃狗粮");
    }
    public void run(){
        System.out.println(this.name+"会跑");
    }
}
class Bird extends Animal{
    public Bird(String name, int age) {
        super(name, age);
    }
    public void eat(){
        System.out.println(this.name+"在吃鸟粮");
    }
    public void fly(){
        System.out.println(this.name+"会飞");
    }
}
class Animal{
    public String name;
    public int age;
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void eat(){
        System.out.println(this.name+"在吃饭");
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal=new Dog("旺财",18);
        Dog dog=(Dog)animal;//要强转类型
        dog.run();//Dog类中特有的方法
        System.out.println("=======");
        Animal animal2=new Bird("小鸟",12);
        Bird bird=(Bird) animal2;//要强转类型
        bird.fly();//Bird类中特有的方法
    }
}

运行代码 

21281240949c45d1bad4775eb2eb84a9.png

2.向下转型的缺点

并不是所有的向下转型都是成功的。

655dac7b18a94886b34688831f9dd55f.png

57860363b23b4fd29afafe3141b260cd.png

3.多态的使用

了解了向上转型和多态之后,我们接着来在Java中来体验多态。

代码演示

class Dog extends Animal{
    public Dog(String name,int age){
        super(name, age);
    }
    @Override  //编译器中方法重写的默认注释
    public void eat() {
        System.out.println(this.name+"在吃狗粮");
    }
}
class Bird extends Animal{
    public Bird(String name, int age) {
        super(name, age);
    }
    public void eat(){
        System.out.println(this.name+"在吃鸟粮");
    }
}
class Animal{
    public String name;
    public int age;
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void eat(){
        System.out.println(this.name+"在吃饭");
    }
}
public class Test {
    public static void func(Animal animal){
        animal.eat();
    }
    public static void main(String[] args) {
        Dog dog=new Dog("旺财",18);
        func(dog);
        System.out.println("=======");
        Bird bird=new Bird("小鸟",12);
        func(bird);
    }
}

129db2974a1744508bc94abd0bc30893.png

1b615045c53a47a9b98a69f6bbfcd19e.png

我们都是通过animal这个引用去调用父类中的eat( )方法,但是由于eat( )对应的对象不同,就调用了各对应子类中的eat( ) 方法,最终导致了结果的不同。这就是多态在Java语言中的体现。 

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

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

相关文章

兵器室管控系统|DW-306是一套成熟系统

概述 智慧兵器室管理系统(DW-S306)是依托互3D技术、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 本解决方案利用现有内部网络,部署部队智能兵器室管理系统&#xff…

Python并发编程学习记录

1、初识并发编程 1.1、串行,并行,并发 串行(serial):一个cpu上按顺序完成多个任务; 并行(parallelism):任务数小于或等于cup核数,多个任务是同时执行的; 并发(concurrency):一个…

小浪助手下载学浪视频的简单步骤

你是否想轻松下载学浪高清视频?快来尝试小浪助手,这是你不可错过的下载神器!简单几步操作,即可轻松下载你所需的学浪视频,节省时间,提高效率! 首先我已经打包好了小浪助手,有需要的…

DOS学习-目录与文件应用操作经典案例-attrib

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 DOS系统中的attrib命令是一个用于显示或更改文件&#…

内网渗透—SMB隧道正反向连接防火墙规则绕过CS上线

1、前言 这篇文章主要是说一下这个用于横向移动的SMB隧道,已经如何使用smb隧道去进行横向移动。 2、实验环境 实验环境和上一篇的差不多,主要是加了个防火墙。 windows server2012 192.168.145.131(外网) 192.168.22.134&…

【NumPy】关于numpy.flatten()函数,看这一篇文章就够了

🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…

头晕、心悸…你们小年轻配不上张俊杰的霸王茶姬,还要奔上市

近日,有多名网友在社交平台反映称,自己在喝了霸王茶姬的新品“万里木兰”奶茶后,出现了失眠、头晕、心悸等不同程度的不适症状,霸王茶姬方面则表示“可能是茶多酚过敏”。 而就在几天前举行的“2024年国际茶日现代东方茶创新论坛…

全局光照技术在AI去衣中的革命性角色

引言: 随着计算机视觉和深度学习技术的飞速发展,AI去衣技术已经逐渐成为图像处理和计算机图形学领域的一个热门话题。这种技术旨在通过算法模型去除或替换图像中的衣物,以服务于娱乐、电子商务、虚拟试衣等多种应用场景。而在实现高质量、真实…

getters的使用

getters的使用 如果state中的数据需要经过处理再使用,就可以利用getters函数

django在线考试系统-计算机毕业设计源码78268

摘 要 本论文主要论述了如何使用python语言、Django框架开发一个在线考试系统,本系统将严格按照软件开发流程,进行各个阶段的工作,面向对象编程思想进行项目开发。在引言中,作者将论述该系统的当前背景以及系统开发的目的&#xf…

VMware虚拟机上安装麒麟V10操作系统

一、安装VMware 在前面的文章中我有具体介绍过如何安装VMware软件,这里就不具体介绍了,需要的同学可以点下面的连接进行下载安装。 玩转Linux—如何在Linux环境中部署MySQL、Redis和nginx_linux系统mysql、redis 主备怎么做-CSDN博客文章浏览阅读1k次&a…

每日百万交易的支付系统,如何设置JVM堆内存大小?

每日百万交易的支付系统,如何设置JVM堆内存大小? 1、支付背景的引入2、支付的核心业务流程3、每日百万交易支付系统的压力在哪里?4、支付系统每秒钟需要处理多少笔支付单5、每个支付订单处理需要耗时多久6、每个支付订单大概需要多大的内存空间7、每秒发起的支付请求对内存的…

c#核心学习1

一、面向对象的概念 1.面向过程编程 2.面向对象编程 3.为什么要学习面向对象编程 提高代码复用率、提高开发效率、提高程序可拓展性、清晰的逻辑关系 4.如何学习 二、面向对象--封装 1)类和对象 1.什么是类 2.类申明在哪里 类一般声明在namespace语句块中 3.…

电商API接口(api商品数据)【电商商品实时数据采集API接口】

众多品牌选择电商API实时数据采集接口进行采购,主要是出于以下几个重要原因: 第一,高效便捷。比价工具通过自动化的方式获取价格信息,避免了繁琐的人工操作,大大节省了时间和精力。 第二,精准比较。API比价…

AIGC 003-Controlnet升级你的SD让图像生成更加可控!

AIGC 003-Controlnet升级你的SD让图像生成更加可控! 文章目录 0 论文工作1 论文方法2 效果 0 论文工作 ControlNet 论文 (Adding Conditional Control to Text-to-Image Diffusion Models) 提出了一种名为 ControlNet 的神经网络结构,旨在为大型文本到图…

IEDA常用快捷键(后续更新ing)

1. 快速生成语句 1.快速生成main()方法 psvm或者main回车 2.快速生成输出语句 sout,回车 3.快速生成for循环 fori或者itar,回车 2.快捷键 含义操作查找文本CtrlF替换文本CtrlR单行注释Ctrl/多行注释CtrlShift/格式化CtrlAltL复制当前内容至下一行CtrlD补全代码Alt/快速生成…

实战复盘:内网环境渗透ms-SQL数据库

渗透环境:如下图所示,web服务器、ms-SQL服务器、PC客户端在同一个网络中,彼此之间,没有路由器或防火墙的隔离,这是一种危险的网络结构,入侵ms-SQL服务器,非常容易。(实战中&#xff…

【C++】二分查找算法

1.题目 2.算法思路 暴力解法:可以将数组遍历一遍,就可以找到。时间复杂度为O(n)。不算太差,可以接受。 但是有更优秀的解法: 就是二分查找算法。 算法的特点:我们所查找的“数组”具有二段性。这里的二段性不一定有…

2024.05.25 第 131 场双周赛

Leetcode 第 131 场双周赛 求出出现两次数字的 XOR 值 [Leetcode 求出出现两次数字的 XOR 值](https://leetcode.cn/problems/find-the-xor-of-numbers-which-appear-twice/description/] 给你一个数组 nums ,数组中的数字 要么 出现一次,要么 出现两次…

【698协议】帧校验算法

698协议,帧校验算法 帧格式 帧校验范围 校验算法 #include "fcs16.h" /* * u16 represents an unsigned 16-bit number. Adjust the typedef for * your hardware. * Drew D. Perkins at Carnegie Mellon University. * Code liberally borrowed from M…