多态的左膀右臂,向上转型与重写

同一个引用 调用了 同一个方法,但是因为引用的对象不一样,所表现的行为不一样,我们把这种思想称为:多态

目录

1.向上转型

1.1.向上转型定义

1.2.向上转型的优缺点

1.3.向上转型的内存指向

1.4.向上转型的三种方式

1.5.向下转型

2.重写

2.1.概念

2.2.重写的规则

2.3.重写与重载

2.4.动态与静态绑定

2.5.避免在构造方法中调用重写的方法

3.使用多态

3.1.简单的多态实现

3.2.实现自定义多态


学会多态的前提:

(1)继承(2)向上转型(3)重写

继承在之前的课程已经介绍过,下面介绍向上转型和重写,这两种也是发生在继承的基础上。

1.向上转型

1.1.向上转型定义

概念:父类引用 引用 子类对象

语法格式:

父类类型 引用名 = new 子类类型();

例如:Parent是父类类型,Son是子类类型,此时就发生了向上转型

Parent p = new Son();
1.2.向上转型的优缺点

优点:

(1)可以实现代码的灵活使用 (2)实现多态的一种条件

缺点:

(1)虽然引用了子类对象,但是也无法访问子类对象中特有的内容

这是一个父子类:

public 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(name+"正在吃……");}}
class Dog extends Animal {public String color;public Dog(String name, int age,String color) {super(name, age);this.color = color;}public void sleep() {System.out.println(name+"正在睡觉!");}
}

当访问的时候: 父类引用无法访问子类单独的方法

(2)但是可以访问父类子类都存在的方法(重写),这种是发生了动态绑定,在下面的重写部分介绍

1.3.向上转型的内存指向

向上转型就相当于,把子类对象当成父类使用。如果需要调用子类独有的属性,需要通过向下转型回来才能使用。

 

1.4.向上转型的三种方式

父类、子类

public 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(name+"正在吃……");}
}
class Dog extends Animal {public String color;public Dog(String name, int age,String color) {super(name, age);this.color = color;}public void eat() {System.out.println("正在吃史");}public void sleep() {System.out.println(name+"正在睡觉!");}
}

1.4.1.直接赋值

第一种:

 public static void main(String[] args) {Dog dog = new Dog("旺财",2,"黄色");Animal animal = dog;//向上转型animal.eat();}

第二种:

public static void main(String[] args) {Animal animal = new Dog("旺财",2,"黄色");animal.eat();}

1.4.2传参方式

public static void func(Animal animal) {animal.eat();animal.age = 3;}public static void main(String[] args) {Dog dog = new Dog("旺旺",1,"黑色");func(dog);}

1.4.3.通过返回值

public static Animal func2() {return  new Dog("旺旺",1,"黑色");}public static void main(String[] args) {Animal animal = func2();animal.name  ="666";}

介绍了向上转型,在下面介绍向下转型。

1.5.向下转型

向下转型一般是使用在向上转型之后,因父类引用无法访问子类特有的方法

转型方式:

  public static void main(String[] args) {Animal animal = new Dog("1",1,"1");animal.eat();Dog dog = (Dog)animal;dog.sleep();((Dog) animal).sleep();}

注意事项:

总结:

向上转型是安全的,而向下转型是不安全的,慎用。比如:狗一定是动物,但是动物不一定是狗。

做法:经历对实现了向上转型的对象,再使用向下转型

2.重写

重写发生的条件:发生继承

2.1.概念

2.1.1.命名

重写,又称为覆写,覆盖。

2.1.2.啥是重写

对父类的方法进行重新编写

例如:

 

2.2.重写的规则

重写的模板:

(1)返回值、形参都不能被修改,必须相同。(返回值如果构成父子类关系也可以)

(2)子类重写的方法的修饰访问权限的大小 >= 父类的

不能被重写的:

(1)被final修饰的方法

(2)静态方法

(3)构造方法

(4)被private修饰的方法

以上父类中的方法都是不能被子类重写的!

注解:

(1)重写的注解:@Override

(2)作用:可以标识是被重写的方法;可以帮助校验重写的格式、语法是否正确,否则会报错。

2.3.重写与重载
区别点重写(Override)重载(Overloading)
参数列表一定不能修改必须修改
返回值类一定不能修改(除非构造父子类关系)可以修改
访问限定符一定不能做到更严格的限制(可以降低限制)可以修改
方法重载是一个类的多态性表现 , 而方法重写是子类与父类的一种多态性表现。

2.4.动态与静态绑定

2.4.1.静态绑定

也称为前期绑定,这种代表就是方法重载,在编译时候(代码写完的时候),根据用户传递的参数就确定了 会调用的方法。

2.4.2.动态绑定

也称为后期绑定,典型代表就是重写。在编译期间,是不确定会调用哪一个方法的,只有在程序运行时,才能确定调用的方法。

2.5.避免在构造方法中调用重写的方法

(1)第一种情况

class B {public B() {func();//在构造方法中,调用重写方法(子类父类都有)}public void func() {System.out.println("B.func()");}
}
class D extends B {@Overridepublic void func() {System.out.println("D.func() ");}
}
public class Test2 {public static void main(String[] args) {D d = new D();}
}

在父类的构造方法中,调用了重写的方法。在实例化子类对象的时候,调用的是子类的func()方法。说明在构造方法内,也会发生动态绑定。

(2)第二种情况

class B {public B() {func();//在构造方法中,调用重写方法(子类父类都有)}public void func() {System.out.println("B.func()");}
}
class D extends B {private int num = 1;@Overridepublic void func() {System.out.println("D.func() "+num);}
}
public class Test2 {public static void main(String[] args) {D d = new D();}
}

实例化子类对象时,为什么不会给num赋值

代码指向顺序:实例化子类对象-->子类构造-->父类的构造方法-->调用重写方法,此时num没有被赋值。(当实例化子类的时候,会给子类对象分配一个内存空间,此时属性都会被加载出来,但是没有进行初始化,就默认为0)

说明:

用尽量简单的方式使对象进入可工作状态 ", 尽量不要在构造器中调用方法 ( 如果这个方法被子类重写 , 就会触
发动态绑定 , 但是此时子类对象还没构造完成 ), 可能会出现一些隐藏的但是又极难发现的问题 .

3.使用多态

在上面介绍向上转型的时候,就已经接触到一点多态的影子了。

一个父类、两个子类

public 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(name+"正在吃……");}
}
class Dog extends Animal {public Dog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("正在吃狗粮……");}
}
class Cat extends Animal {public Cat(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("正在吃鱼翅……");}
}
3.1.简单的多态实现

3.1.1.先发生重写

3.1.2.发生向上转型

我们使用传参的方式进行向上转型

  public static void func(Animal animal) {animal.eat();}public static void main(String[] args) {Dog dog = new Dog("小狗",1);Cat cat = new Cat("小猫",2);func(dog);func(cat);}

3.1.3.多态的发生

(1)多态发生

(2)多态的概念

同一个引用 调用了 同一个方法,但是因为引用的对象不一样,所表现的行为不一样,我们把这种思想称为:多态

3.2.实现自定义多态

下面这种实现的方向,才是以后多态实现的常用手段。一般是通过返回值实现多态

类:

public 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(name+"正在吃……");}
}
class Dog extends Animal {public Dog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println(name+"正在吃狗粮……");}
}
class Cat extends Animal {public Cat(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println(name+"正在吃鱼翅……");}
}

main函数:

import java.util.Scanner;public class Test {public static void func1(Animal animal) {animal.eat();}public static Animal func(int q) {Scanner in = new Scanner(System.in);if(q == 1) {System.out.print("输入名字:");String s = in.nextLine();System.out.print("输入年龄:");int b = in.nextInt();return new Dog(s,b);}else {System.out.print("输入名字:");String s = in.nextLine();System.out.print("输入年龄:");int b = in.nextInt();return new Cat(s,b);}}public static void main(String[] args) {Scanner in = new Scanner(System.in);int q = 0;do {System.out.println("请输入你的身份:1(dog)/2(cat)");q = in.nextInt();Animal animal = func(q);animal.eat();}while (q == 1 || q == 2);}
}

运行结果:


本节的多态知识就介绍到这里了,快去按照代码练习一下吧。

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【学习】软件测试行业未来的发展趋势预测

近年来,随着中国数字经济的蓬勃发展,软件测试行业也迎来了新的春天。从早期的手工测试到自动化测试,再到持续集成和持续交付,中国的软件测试行业经历了快速的发展和变革。各行各业均对软件测试提出了更高的要求,尤其在…

项目1-加法计算器

1.创建项目 2.导入前端代码 2.1 static包内 2.2 测试前端代码是否有误 显示成功说明无误 2.3 定义用户接口 请求路径:calc/sum 请求方式:GET/POST 接口描述:计算两个整数相加 请求参数: 参数名类型是否必须备注num1Integer是参与计算的第…

python学习9:python的代码中的数据类型转换

python中数据类型的转换 1.为什么需要转换类型呢? 数据类型之间,在特定的场景下,是可以相互转换的,如字符串转数字,数字转字符串等;数据类型转换,在以后是我们经常使用到的功能,例如…

【MySQL】复合查询——基本单表查询、多表查询、自连接、子查询、使用from进行子查询、合并查询

文章目录 MySQL复合查询1. 基本单表查询2. 多表查询3. 自连接4. 子查询4.1 单行子查询4.2 多行子查询4.3 多列子查询4.4 使用from进行子查询 5. 合并查询5.1 union5.2 union all MySQL 复合查询 数据库的复合查询是指在一个查询中结合使用多个查询条件或查询子句,以…

前端学习之用css和html做一个仿淘宝的导航栏

代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>仿淘宝界面案例</title><style>/* 最外层盒子 */.container{width: 270px;height: 385px;border: 1px solid rgb(255, 208, 0);bord…

MISC:zip压缩包伪加密破解及其结构解析

一.前言 遇到zip压缩包是被加密的&#xff0c;但加密有时侯是伪加密&#xff0c;需要我们进行破解。 二.压缩包解析 1. 压缩源文件数据区 zip文件头标记 文件头&#xff1a;504B0304 解压文件所需的pkware版本 全局方式位标记 如果四位中的第二位为奇数则表示有加密&#xff…

基于LLM的数据质量错误检测

原文地址&#xff1a;automated-detection-of-data-quality-issues 2024 年 3 月 23 日 本文是有关使用大型语言模型 (LLM) 清理数据的系列文章中的第二篇文章&#xff0c;重点是识别表格数据集中的错误。 该图概述了我们将在本文中探讨的方法&#xff0c;该方法侧重于在最少的…

检索增强生成(RAG)技术:实现流程、作用及应用案例

一. RAG简介 在自然语言处理&#xff08;NLP&#xff09;领域中&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;技术巧妙地结合了信息检索与神经网络生成模型的力量&#xff0c;通过在生成过程中引入相关的外部信息&#xff0c;实现了在…

红外遥控器的使用和详细解释

infrared.c #include "infrared.h"/* 红外 --- PA8*/void Infrared_Init(void) {GPIO_InitTypeDef GPIO_InitStruct; EXTI_InitTypeDef EXTI_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;//使能SYSCFG时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, E…

Zabbix使用TimescaleDB数据库

一、前言 Zabbix 6.0 已发布很久&#xff0c;下个季度7.0应该会正式发布&#xff0c;但6.0也有许多新功能和新特性&#xff0c;这里介绍 6.0 配置 TimescaleDB&#xff0c;此安装配置方法可基本通用与其他版本。 二、TimescaleDB TimescaleDB 基于 PostgreSQL 数据库打造的一…

Power BI ----SVG(圆环图)

圆环图助力矩阵图 定义度量值放置视觉对象 SVG是什么鬼&#xff0c;在现在的Web世界中越来越凸显这一标准的优势。关于SVG&#xff0c;我们只需要知道一点就好 ---- SVG 意为可缩放矢量图形&#xff08;Scalable Vector Graphics&#xff09;。它是使用 XML 格式定义的图像。 由…

pytorch 实现多层神经网络MLP(Pytorch 05)

一 多层感知机 最简单的深度网络称为多层感知机。多层感知机由 多层神经元 组成&#xff0c;每一层与它的上一层相连&#xff0c;从中接收输入&#xff1b;同时每一层也与它的下一层相连&#xff0c;影响当前层的神经元。 softmax 实现了 如何处理数据&#xff0c;如何将 输出…