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

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语言中的体现。 

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

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

相关文章

微信小程序源码-基于Java后端的小区租拼车管理信息系统毕业设计(附源码+演示录像+LW)

大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:微信小程序毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设…

跟TED演讲学英文:How to escape education‘s death valley by Sir Ken Robinson

How to escape education’s death valley Link: https://www.ted.com/talks/sir_ken_robinson_how_to_escape_education_s_death_valley Speaker: Sir Ken Robinson Date: April 2013 文章目录 How to escape educations death valleyIntroductionVocabularySummaryTranscri…

使用残差网络识别手写数字及MNIST 数据集介绍

MNIST 数据集已经是一个几乎每个初学者都会接触的数据集, 很多实验、很多模型都会以MNIST 数据集作为训练对象, 不过有些人可能对它还不是很了解, 那么今天我们一起来学习一下MNIST 数据集。 1.MNIST 介绍 MNIST 数据集来自美国国家标准与技术研究所, National Institute of S…

Spring MVC+mybatis项目入门:旅游网(四)用户注册——mybatis的配置与使用以及Spring MVC重定向

个人博客:Spring MVCmybatis项目入门:旅游网(四)用户注册2-持久化 | iwtss blog 先看这个! 这是18年的文章,回收站里恢复的,现阶段看基本是没有参考意义的,技术老旧脱离时代(2024年…

MiniMax 悄咪咪上线的这款 AI 产品,好用到爆炸!

大模型太卷了!上周国外某款多模态大模型的出现,立刻掀起了 AI 领域对话式多模态交互的热潮。不管是文字、语音,还是图片,都能与你进行实时交互。随后,谷歌也推出了类似的 Astra。 然而,国外的交互式大模型…

线性回归模型之套索回归

概述 本案例是基于之前的岭回归的案例的。之前案例的完整代码如下: import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import Ridge, LinearRegression from sklearn.datasets import make_regression from sklearn.model_selectio…

2024年弘连网络FIC大会竞赛题线下决赛题

总结: FIC决赛的时候,很多小问题没发现,在pve平台做题确实很方便。 这套题目复盘完,服务器这块的知识确实收获了很多,对pve集群平台和网络拓扑也有了一定的认识,感谢各位大佬悉心指导。 接下来&#xff0…

【数据结构】哈希表的原理及其实现

文章目录 哈希表的概念哈希函数的设计常见的哈希函数 哈希冲突1. 闭散列代码实现 2. 开散列拉链法的优点 针对开散列哈希的扩展基于开散列拉链法封装哈希表MyHash.h 基于哈希表实现unordered_map类Myunordered_map.h 基于哈希表实现unordered_set类Myunordered_map.h 哈希表的概…

ROCm上运行Transformer

10.7. Transformer — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import math import pandas as pd import torch from torch import nn from d2l import torch as d2l#save class PositionWiseFFN(nn.Module):"""基于位置的前馈网络""&qu…

解决Error: error:0308010C:digital envelope routines::unsupported的四种解决方案

问题描述: 报错:Error: error:0308010C:digital envelope routines::unsupported 报错原因: 主要是因为 nodeJs V17 版本发布了 OpenSSL3.0 对算法和秘钥大小增加了更为严格的限制,nodeJs v17 之前版本没影响&am…

Rust后台管理系统Salvo-admin源码编译

1.克隆salvo-admin后台管理系统源码: https://github.com/lyqgit/salvo-admin.git 2.编译 编译成功 3.创建mysql数据库与执行sql脚本 输入名称ry-vue 执行sql脚本 全部执行上面3个sql 修改数据库用户名与密码: 清理及重新编译 cargo clean cargo build 4.运行并测试 cargo…

基于JAVA GUI体育馆管理系统的会员功能

Java GUI即Java图形用户界面,是一种使用图形化元素(如窗口、按钮、文本框等)来构建用户界面的技术。它基于Java的Swing框架,可以用于创建各种复杂的用户界面,包括窗口、对话框、菜单、按钮、文本框、复选框、下拉列表等…

仅需一块 4GB 的 GPU ,就能运行开源大语言模型:Llama3 70B

最强的开源大语言模型 Llama3 已经发布一段时间了,一些盆友资源有限,私信询问是否可以使用 4GB 的 VRAM 在本地运行 Llama3 70B。 与 GPT-4 相比,Llama3 的性能如何?Llama3 使用了哪些关键的前沿技术使其变得如此强大&#xff1f…

Oracle 并行和 session 数量的

这也就是为什么我们指定parallel为4,而实际并行度为8的原因。 insert create index,发现并行数都是加倍的 Indexes seem always created with parallel degree 1 during import as seen from a sqlfile. The sql file shows content like: CREATE INDE…

SwiftUI中List的样式及使用详解(添加、移动、删除、自定义滑动)

SwiftUI中的List可是个好东西,它用于显示可滚动列表的视图容器,类似于UITableView。在List中可以显示静态或动态的数据,并支持垂直滚动。List是一个数据驱动的视图,当数据发生变化时,列表会自动更新。 针对List&#x…

windows 7 10 11快捷键到启动页面

1.快速打开用户启动文件夹 shell:startup 方式2:快速打开系统启动文件夹 shell:Common Startup shell:Common Startup

燃数科技前端25-40K*14薪一面超简单,下周二面啦

​​​​​​​ 文章末尾扫描二维码领取地址 一面 1、自我介绍 2、低代码如何设计的 3、react路由原理 4、react生命周期 5、什么是回调地狱,如何解决 6、jwt和session有什么区别 7、js文件相互引用有什么问题?如何解决 8、一个很大的json文件…

腾讯TDSQL-C灰度发布列存索引; Azure Copilot集成支持Azure上各种托管数据库;

重要更新 1. Copilot for Azure新增了对Azure SQL、 Azure Database for MySQL的支持([8] [14])。Copilot for Azure是微软云提供的基于大模型技术的助手工具,主要能力包括了:该大模型可以获得最新的文档,以及客户的Azure资源情况&#xff0c…

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

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

9.3 Go语言入门(变量声明和函数调用)

Go语言入门(变量声明和函数调用) 目录二、变量声明和函数调用1. 变量声明1.1 使用 var 关键字声明1.2 简短声明1.3 零值1.4 常量 2. 函数调用2.1 函数定义2.2 多个返回值2.3 命名返回值2.4 可变参数2.5 匿名函数和闭包 目录 Go 语言(Golang&a…