多态(polymorphism)
2020-10-17 longzqa@163.com stronglzq
【摘要】针对多态及相关知识进行阐述。继承关系中,多个子类都需要调用一个父类抽象方法,使用多态写法;采用多态写法后,无法调用子类特有方法,则需采用对象的向下转型。文章的行为逻辑为:
[多态是什么] -->[什么情况下使用多态写法] -->[如何使用多态] -->[多态存在什么缺陷] -->[多态缺陷的解决方案:向下转型] -->[向下转型缺陷及instanceof]
多态简述
多态是什么?面向对象编程(Object-Oriented Programming, OOP)的三大特性为封装(encapsulation)、继承(inheritance)、多态(polymorphism),其中多态是指一个对象有多种状态、多种“身份”,多态的前提条件存在上下级关系的类,如继承关系、接口实现关系。以继承关系为例,下图中,子类“Cat”的实例“cat”既是"Cat",又是“Animal”,即子类对象既是子类,又是父类。
注:多态的概念是对于“对象”的,对象有多种状态。
什么情况下适合使用多态?当多个子类都需要调用父类的某方法时,适合采用多态写法。例如下面例子中,子类“Cat”和“Dog”都需要调用父类“Animal”的“eat()”方法,此时适合采用多态写法。
public abstract class Animal{
// 抽象方法 eat
public abstract void eat();
}
public class Cat extends Animal{
// 覆盖重写父类的方法eat()
@Override
public void eat(){
System.out.println("猫吃鱼");
}
}
public class Dog extends Animal(){
@Override
public void eat(){
System.out.println("吃狗粮");
}
}
public class Demo{
public abstract void main(String[] args){
// 多态写法,左侧父类引用指向右侧子类对象
Animal animal = new Cat;
animal.eat();
}
}
多态缺陷及对象向下转型
多态的核心在于将子类对象看作父类来使用,此时存在一个缺陷,使用多态时,无法调用子类的特有方法,针对该缺陷,解决方案为对象的向下转型,通过转型后的对象来调用子类的特有方法。
对象的向下转型为将“看作为父类”使用的子类对象,向下转型为“子类对象”来使用,语法为父类 子类变量 = (父类)子类对象
。例如上述例子中“animal”向下转型为“Cat”类来使用,语句为Cat cat = (Cat)animal;
,例如:
public class Cat{
@Override
public void eat(){
System.out.println(“猫吃鱼”);
}
// 特有方法
public void uniqueCatMethod(){
System.out.println("猫特有方法");
}
}
public class Demo{
public static void main(String[] args){
// 多态写法,左侧父类引用指向右侧子类对象
Animal animal = new Cat();
// 调用父类方法
animal.eat();
//向下转型,调用子类特有方法
Cat cat = (Cat)animal;
cat.uniqueCatMethod();
}
}
向下转型缺陷及instanceof
进行向下转型时,必须转型回相应的子类,不然会报错“ClassCastException”,当子类较多时,常常会犯个错误,向下转型为其他的子类,导致报错。针对于该问题,解决方法为,在进行向下转型前,先判断该引用与子类是否一致,语句为if(animal instanceof Cat)
,例如在上述例子中,进行向下转型前进行判断:
public class Demo{
public static void main(String[] args){
// 多态写法,左侧父类引用指向右侧子类对象
Animal animal = new Cat();
animal.eat();
// instanceof判断,并向下转型
if(animal instanceof Cat){
Cat cat = (Cat)animal;
cat.uniqueCatMethod();
}else if(animal instanceof Dog){
Dog dog = (Dog)animal;
dog.uniqueDogMethod();
}
}
}
多态(polymorphism)的更多相关文章
- 7.6 GRASP原则六: 多态 Polymorphism
GRASP原则六: 多态 Polymorphism How to handle alternative behaviors based on type 如何处理依据类型不同而有 不同行为的一类需求 ...
- 《编程导论(Java)·2.1.2 啊,我看到了多态》-什么是多态(polymorphism)
1.不明觉厉 很多人学习多态时,会认为. 之所以不明觉厉,由于多态的定义:事物存在的多种表现形态:而后,有人将重载(overload).改写(override).多态变量和泛型归结于同一个术语&quo ...
- java面向对象之 多态 Polymorphism
多态(Polymorphism):用我们通俗易懂的话来说就是子类就是父类(猫是动物,学生也是人),因此多态的意思就是:父类型的引用可以指向子类的对象. 1.多态的含义:一种类型,呈现出多种状态 主要讨 ...
- C++ 多态Polymorphism 介绍+动态绑定、静态绑定
什么是多态? 多态(polymorphism)一词最初来源于希腊语polumorphos,含义是一种物质的多种形态. 在专业术语中,多态是一种运行时绑定机制(run-time binding) ,通过 ...
- 多态polymorphism,向上转型和动态方法调度有什么用?
多态有什么用?马 克 - t o - w i n:https://blog.csdn.net/qq_44639795/article/details/103117332我给大家想了两个 ...
- Java笔记(十五)……面向对象IV多态(polymorphism)
概述 定义:某一类事物的多种存在形态. 例:动物中猫,狗. 猫这个对象对应的类型是猫类型 猫 x = new 猫(); 同时猫也是动物中的一种,也可以把猫称为动物. 动物 y = new 猫(); 动 ...
- [18/12/03] 多态(polymorphism)和对象的转型(casting)
一.多态 多态指的是同一个方法调用,由于对象不同可能会有不同的行为.现实生活中,同一个方法,具体实现会完全不同. 比如:同样是调用人的“休息”方法,张三是睡觉,李四是旅游,同样是调用人“吃饭”的方法, ...
- 多态(Polymorphism)的实现机制
1. 我理解的广义的 override 是指抛开各种访问权限,子类重定义(redefine)父类的函数(即函数签名相同). 2. C++中的三个所谓的原则:never redefine base cl ...
- Java学习之 多态 Polymorphism
转自:http://www.cnblogs.com/mengdd/archive/2012/12/25/2832288.html 多态的概念 多态==晚绑定. 不要把函数重载理解为多态. 因为多态是一 ...
- 重构指南 - 使用多态代替条件判断(Replace conditional with Polymorphism)
多态(polymorphism)是面向对象的重要特性,简单可理解为:一个接口,多种实现. 当你的代码中存在通过不同的类型执行不同的操作,包含大量if else或者switch语句时,就可以考虑进行重构 ...
随机推荐
- SpringBoot写后端接口,看这一篇就够了!
摘要:本文演示如何构建起一个优秀的后端接口体系,体系构建好了自然就有了规范,同时再构建新的后端接口也会十分轻松. 一个后端接口大致分为四个部分组成:接口地址(url).接口请求方式(get.post等 ...
- Node.js 从零开发 web server博客项目[登录]
web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...
- Redis安装即python使用
一:简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted ...
- 一个提高N倍系统新能的编程点,却总是被普通开发们遗忘
位运算这个概念并不陌生,大多数程序员在进入这个领域的时候或多或少都接触过位运算,估计当时都写过不少练习题的. 位运算本身不难,困难的是大家没有学会在系统设计时用上它,提高系统性能,增加你的不可替代性. ...
- [HarekazeCTF2019]Avatar Uploader 1 &&
[HarekazeCTF2019]Avatar Uploader 1 这是一个文件上传的题目,但是这导体是通过满足条件来获取flag的. 他有两个函数,一个是getimagesize,还有一个是FIL ...
- 命令执行漏洞攻击&修复建议
应用程序有时需要调用一些执行系统命令的函数,如在PHP中,使用system.exec.shell_exec.passthru.popen.proc_popen等函数可以执行系统命令.当黑客能控制这些函 ...
- Python-集合 字典-set dict fronzenset
集合 set 1. 无序 2. 去重 3. 定义空集 set() numbers = {1, 3, 4, 5, 6, 5, 4, 4, 7, 8} print(numbers) print(numbe ...
- 02 ArcPython的使用大纲
一.什么情况下使用ArcPython? 1.现有工具实现不了,可以用python 2.流程化需要时,可以使用python 3.没有AE等二次开发环境 4.其他特殊场景 二.ArcPython在ArcG ...
- C++ 中explicit的作用
转载:https://www.cnblogs.com/diligenceday/p/5781408.html C++ 中explicit的作用 explicit作用: 在C++中,explicit ...
- OpenCV图像加载与保存
OpenCV中的图像加载与保存 头文件是包含的库,在GitHub上下载的 imread("图片路径",图片加载方式) 图片加载方式: IMREAD_GRAYSCALE 灰度图像 I ...