Java面向对象之多态、向上转型和向下转型

文章目录

  • 前言
  • 一、多态
  • 二、引用类型之间的转换
      • Ⅰ.向上转型
      • Ⅱ.向下转型
  • 总结


前言

 今天继续Java面向对象的学习,学习面向对象的第三大特征:多态,了解多态的意义,以及两种引用类型之间的转换:向上转型、向下转型。
 希望能对你的学习有所帮助!


提示:以下是本篇文章正文内容,Java系列学习将会持续更新

一、多态

(1)基本概念

多态就是指一个引用可以表示多种状态。意义在于实现参数统一化。

饮料:可乐、雪碧、红牛、美年达、…
宠物:狗、猫、鸟、…
整数: byte b = 10; short s = 10; int i = 10;…

C++多态分为两种:编译多态、运行时多态

Java的多态只有一种,就是运行时多态。是一种运行期间的行为,而不是编译期的行为。

(2)语法格式

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

 	Person ps = new Student();
 	ps.show();

解析:
  在编译阶段ps是Person类型,因此调用Person类自己的show()方法,若没有则编译的时候就报错。
  在运行阶段ps真正指向的对象是Student类型,因此最终调用的是Student类中自己的show()方法。

  当使用多态方式调用方法的时候,首先会检查父类中是否有该方法,如果没有,则编译报错。
  如果有,再去调用子类的同名方法。(注意:静态static方法属于特殊情况,静态方法只能继承,不能重写override,如果子类中定义了同名同形式的静态方法,它对父类方法只能起到隐藏的作用。调用的时候用谁的引用,则调用谁的版本。)

多态存在的三个比较条件:
  1.要有继承
  2.要有重写
  3.父类的引用指向子类的对象

(3)多态的效果

 1.对于指向子类对象的父类来说,在编译期间只能调用父类的方法,不能直接调用子类的方法。
 2.对于父子类都有的非静态方法来说,最终调用子类中的重写版本。
 3.对于父子类中都有的静态方法来说 ,最终调用父类中的版本,与指向的对象类型无关。

(4)案例

public class TestPersonStudent {
	public static void main(String[] args) {
	
		//使用父类的引用指向父类自己的对象
		Person p = new Person();
		p.show(); 
        /**
         * 运行结果:
         * 小白  18
         */
         
		//使用子类的引用指向子类自己的对象
		System.out.println("--------------------");
		Student s = new Student();
		s.show();
        /**
         * 运行结果:
         * 小白  18
         * 学号是1
         */
		
		//使用父类的引用指向子类的对象,形成多态
		System.out.println("--------------------");
		//发生由Student类型向Person类型的转换,小范围向大范围,自动类型转换
		Person ps = new Student("小黑",19,2);
		//解析:在编译期间调用的是Person.show(),在执行期间调用的是Student.show()
		ps.show();
		/**
         * 运行结果:
         * 小黑  19
         * 学号是2
         */
        
		//使用ps调用非静态方法进行测试
		System.out.println("--------------------");
		String str = ps.getName();
		//ps是Person类型的引用,因此可以调用Person类的方法
		System.out.println("获取到的名字是"+str);
		/*
		 * int num = ps.getId(); (X)
		 * 子类可访问调用父类的信息,但父类无法访问调用子类
		 */
		/**
         * 运行结果:
         * 获取到的名字是小黑
         */ 
        
		//使用ps调用静态方法进行测试
		System.out.println("--------------------");
		ps.test(); //警告
		Person.test(); //静态成员推荐使用类名.的方式访问
		//ps.test2(); (X)
		Student.test(); //当Student类中没有test()时,会自动调用父类中的test()
		Student.test2();
		/**
         * 运行结果:
         * Person类的静态方法
         * Person类的静态方法
         * Person类的静态方法
         * Student类的静态方法
         */
        
		//如何实现子类方法的调用
		System.out.println("--------------------");
		//由Person类型向Student类型的转换,大-》小,强制类型转换
		Student st = (Student) ps;
		int num = st.getId();
		System.out.println("ID是"+num);
        /**
         * 运行结果:
         * ID是2
         */
	}
}

回到目录…

二、引用类型之间的转换

(1)基本概念
  引用类型之间的转换必须发生在父子类之间,分为自动类型转换(向上转型)和强制类型转换(向下转型)。

Ⅰ.向上转型

父类引用指向子类对象:

Animal dog = new Dog();

把一个子类对象转换为父类对象,这种转型一共发生在三个地方:

①产生对象时

Animal animal = new Dog();

②方法参数传递

public void fun(Animal animal){}

fun(new Dog());

③方法返回值

public Animal test(){
   return new Dog();
}

注意:
  当执行animal.eat();时,因为new的是子类Dog,所以是运行子类重写父类的方法以及父类派生的方法,无法调用子类独有的方法。若子类没有重写,则调用父类的方法。
  父类中的静态方法无法被子类重写,所以向上转型之后只能调用父类原有的静态方法。

Ⅱ.向下转型

  子类引用指向父类实例,必须进行强制类型转换,可以调用子类特有的方法。

	Animal animal = new Bird();
	Bird bird = (Bird) animal;
	bird.fly();

这种转型有一定的风险性:

	Person ps = new Student(“小黑”,19,2);
	Teacher t = (Teacher)ps;  (X)

  当没有父子类关系发生强制类型转换则编译报错,当拥有父子类关系发生强制转换是编译通过;若目标类型并不是该引用真正指向的类型时,在运行阶段发生类型转换异常。

转型的前提:必须满足转型的条件

  为了避免上述错误的发生,通常只要进行强制类型转换就需要进行判断,格式如下:
if (引用变量名 instanceof 数据类型) {}

  instanceof 运算符可以进行判断,左侧对象是否满足右侧对象类型的特征。满足则返回true,否则返回false

 if(animal instanceof Bird){}

回到目录…


总结

提示:这里对文章进行总结:
以上就是今天的学习内容,本文是继续Java面向对象的学习,学习了多态、向上转型、向下转型,这些内容刚开始会觉得难理解,多写就会熟悉。之后的学习内容将持续更新!!!

热门文章

暂无图片
编程学习 ·

exe4j详细使用教程(附下载安装链接)

一、exe4j介绍 ​ exe4j是一个帮助你集成Java应用程序到Windows操作环境的java可执行文件生成工具,无论这些应用是用于服务器,还是图形用户界面(GUI)或命令行的应用程序。如果你想在任务管理器中及Windows XP分组的用户友好任务栏…
暂无图片
编程学习 ·

AUTOSAR从入门到精通100讲(126)-浅谈车载充电系统通信方案

01 引言 本文深入研究车载充电系统策略,设计出一套基于电动汽车电池管理系统与车载充电机的CAN通信协议,可供电动汽车设计人员参考借鉴。 02 电动汽车充电系统通讯网络 电动汽车整车控制系统中采用的是CAN总线通信方式,由一个整车内部高速CAN网络、内部低速CAN网络和一个充电…
暂无图片
编程学习 ·

CMake(九):生成器表达式

当运行CMake时,开发人员倾向于认为它是一个简单的步骤,需要读取项目的CMakeLists.txt文件,并生成相关的特定于生成器的项目文件集(例如Visual Studio解决方案和项目文件,Xcode项目,Unix Makefiles或Ninja输入文件)。然…
暂无图片
编程学习 ·

47.第十章 网络协议和管理配置 -- 网络配置(八)

4.3.3 route 命令 路由表管理命令 路由表主要构成: Destination: 目标网络ID,表示可以到达的目标网络ID,0.0.0.0/0 表示所有未知网络,又称为默认路由,优先级最低Genmask:目标网络对应的netmaskIface: 到达对应网络,应该从当前主机哪个网卡发送出来Gateway: 到达非直连的网络,…
暂无图片
编程学习 ·

元宇宙技术基础

请看图: 1、通过AR、VR等交互技术提升游戏的沉浸感 回顾游戏的发展历程,沉浸感的提升一直是技术突破的主要方向。从《愤怒的小鸟》到CSGO,游戏建模方式从2D到3D的提升使游戏中的物体呈现立体感。玩家在游戏中可以只有切换视角,进而提升沉浸…
暂无图片
编程学习 ·

flink的伪分布式搭建

一 flink的伪分布式搭建 1.1 执行架构图 1.Flink程序需要提交给 Job Client2.Job Client将作业提交给 Job Manager3.Job Manager负责协调资源分配和作业执行。 资源分配完成后,任务将提交给相应的 Task Manage。4.Task Manager启动一个线程以开始执行。Task Manage…
暂无图片
编程学习 ·

十进制正整数与二进制字符串的转换(C++)

Function one: //十进制数字转成二进制字符串 string Binary(int x) {string s "";while(x){if(x % 2 0) s 0 s;else s 1 s;x / 2;}return s; } Function two: //二进制字符串变为十进制数字 int Decimal(string s) {int num 0, …
暂无图片
编程学习 ·

[含lw+源码等]微信小程序校园辩论管理平台+后台管理系统[包运行成功]Java毕业设计计算机毕设

项目功能简介: 《微信小程序校园辩论管理平台后台管理系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序做的辩论管理前台和Java做的后台管理系统: 微信小程序——辩论管理前台涉及技术:WXML 和 WXS…
暂无图片
编程学习 ·

树莓派驱动DHT11温湿度传感器

1,直接使用python库 代码如下 import RPi.GPIO as GPIO import dht11 import time import datetimeGPIO.setwarnings(True) GPIO.setmode(GPIO.BCM)instance dht11.DHT11(pin14)try:while True:result instance.read()if result.is_valid():print(ok)print(&quo…
暂无图片
编程学习 ·

ELK简介

ELK简介 ELK是三个开源软件的缩写,Elasticsearch、Logstash、Kibana。它们都是开源软件。不过现在还新增了一个 Beats,它是一个轻量级的日志收集处理工具(Agent),Beats 占用资源少,适合于在各个服务器上搜集日志后传输给 Logstas…
暂无图片
编程学习 ·

Linux 基础

通常大数据框架都部署在 Linux 服务器上,所以需要具备一定的 Linux 知识。Linux 书籍当中比较著名的是 《鸟哥私房菜》系列,这个系列很全面也很经典。但如果你希望能够快速地入门,这里推荐《Linux 就该这么学》,其网站上有免费的电…
暂无图片
编程学习 ·

Windows2022 无线网卡装不上驱动

想来 Windows2022 和 windows10/11 的驱动应该差不多通用的,但是死活装不上呢? 搜一下,有人提到 “默认安装时‘无线LAN服务’是关闭的,如果需要开启,只需要在“添加角色和功能”中,选择开启“无线LAN服务…
暂无图片
编程学习 ·

【嵌入式面试宝典】版本控制工具Git常用命令总结

目录 创建仓库 查看信息 版本回退 版本检出 远程库 Git 创建仓库 git initgit add <file> 可反复多次使用&#xff0c;添加多个文件git commit -m <message> 查看信息 git status 仓库当前的状态git diff 差异对比git log 历史记录&#xff0c;提交日志--pret…
暂无图片
编程学习 ·

用Postman生成测试报告

newman newman是一款基于nodejs开发的可以运行postman脚本的工具&#xff0c;使用Newman&#xff0c;可以直接从命令运行和测试postman集合。 安装nodejs 下载地址&#xff1a;https://nodejs.org/en/download/ 选择自己系统相对应的版本内容进行下载&#xff0c;然后傻瓜式安…
暂无图片
编程学习 ·

IntelliJ IDEA 的 Metamodel 配置

如果不在 IntelliJ IDEA 中配置的话&#xff0c;将会出现编译错误。 这是因为 Metamodel 源代码不是在 src 目录中的&#xff0c;而是在编译的时候生成的。 要解决这个问题其实也非常简单&#xff0c;按照下面 2 个步骤就可以了。 配置 首先需要进入进入 IntelliJ IDEA 的编…