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)的更多相关文章

  1. 7.6 GRASP原则六: 多态 Polymorphism

    GRASP原则六: 多态 Polymorphism  How to handle alternative behaviors based on type 如何处理依据类型不同而有 不同行为的一类需求 ...

  2. 《编程导论(Java)·2.1.2 啊,我看到了多态》-什么是多态(polymorphism)

    1.不明觉厉 很多人学习多态时,会认为. 之所以不明觉厉,由于多态的定义:事物存在的多种表现形态:而后,有人将重载(overload).改写(override).多态变量和泛型归结于同一个术语&quo ...

  3. java面向对象之 多态 Polymorphism

    多态(Polymorphism):用我们通俗易懂的话来说就是子类就是父类(猫是动物,学生也是人),因此多态的意思就是:父类型的引用可以指向子类的对象. 1.多态的含义:一种类型,呈现出多种状态 主要讨 ...

  4. C++ 多态Polymorphism 介绍+动态绑定、静态绑定

    什么是多态? 多态(polymorphism)一词最初来源于希腊语polumorphos,含义是一种物质的多种形态. 在专业术语中,多态是一种运行时绑定机制(run-time binding) ,通过 ...

  5. 多态polymorphism,向上转型和动态方法调度有什么用?

    多态有什么用?马 克  -   t   o - w   i  n:https://blog.csdn.net/qq_44639795/article/details/103117332我给大家想了两个 ...

  6. Java笔记(十五)……面向对象IV多态(polymorphism)

    概述 定义:某一类事物的多种存在形态. 例:动物中猫,狗. 猫这个对象对应的类型是猫类型 猫 x = new 猫(); 同时猫也是动物中的一种,也可以把猫称为动物. 动物 y = new 猫(); 动 ...

  7. [18/12/03] 多态(polymorphism)和对象的转型(casting)

    一.多态 多态指的是同一个方法调用,由于对象不同可能会有不同的行为.现实生活中,同一个方法,具体实现会完全不同. 比如:同样是调用人的“休息”方法,张三是睡觉,李四是旅游,同样是调用人“吃饭”的方法, ...

  8. 多态(Polymorphism)的实现机制

    1. 我理解的广义的 override 是指抛开各种访问权限,子类重定义(redefine)父类的函数(即函数签名相同). 2. C++中的三个所谓的原则:never redefine base cl ...

  9. Java学习之 多态 Polymorphism

    转自:http://www.cnblogs.com/mengdd/archive/2012/12/25/2832288.html 多态的概念 多态==晚绑定. 不要把函数重载理解为多态. 因为多态是一 ...

  10. 重构指南 - 使用多态代替条件判断(Replace conditional with Polymorphism)

    多态(polymorphism)是面向对象的重要特性,简单可理解为:一个接口,多种实现. 当你的代码中存在通过不同的类型执行不同的操作,包含大量if else或者switch语句时,就可以考虑进行重构 ...

随机推荐

  1. 内存管理初始化源码2:setup_arch

    PFN相关宏说明: /* kernel/include/linux/pfn.h */ PFN : Page Frame Number(物理页帧) /* * PFN_ALIGN:返回地址x所在那一页帧的 ...

  2. 分布式系统监视zabbix讲解三之用户和用户组

    概述 Zabbix 中的所有用户都通过 Web 前端去访问 Zabbix 应用程序.并为每个用户分配唯一的登陆名和密码. 所有用户的密码都被加密并储存于 Zabbix 数据库中.用户不能使用其用户名和 ...

  3. 1500多套微信小程序带后端源码-史上最全的不同行业的源码集合

    如何下载获取在最后面! 部分源码 部分源码 部分源码 部分截图 o2o行业 | - 盒马鲜生 | - 轻客洗衣 互联网行业 | - 云文档 | - 仿ofo共享单车 | - 仿美团外卖 | - 仿饿了 ...

  4. Redis可视化工具推荐

    前言 Redis可视化工具目前好用的免费的几乎难以寻迹,百度能搜索到的推荐比较多的是Redis Desktop Manager 官网地址:https://redisdesktop.com/pricin ...

  5. Spring Boot学习(四)常用注解

    一.注解对照表 注解 使用位置 作用  @Controller  类名上方  声明此类是一个SpringMVC Controller 对象,处理http请求  @RequestMapping  类或方 ...

  6. PHP序列化与反序列化学习

    序列化与反序列化学习 把对象转换为字节序列的过程称为对象的序列化:把字节序列恢复为对象的过程称为对象的反序列化. <?php class UserInfo { public $name = &q ...

  7. Linux系统编程—条件变量

    条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用.条件变量之所以要和互斥锁一起使用,主要是因为互斥锁的一个明显的特点就是它只有两种状态:锁定和非锁定,而条件变量可以通过允许线程阻塞和等 ...

  8. Spark 模型选择和调参

    Spark - ML Tuning 官方文档:https://spark.apache.org/docs/2.2.0/ml-tuning.html 这一章节主要讲述如何通过使用MLlib的工具来调试模 ...

  9. Python-获取文件状态模块-os stat lastat fstat path

    案例: 在某项目中,需要获取文件状态,如: 文件的类型(普通文件.目录.符合连接.设备文件) 文件的访问权限 文件最后 访问.修改.节点状态 时间 普通文件大小 -- 如何解决? 方法1:通过os原始 ...

  10. Mbedtls和Opesnssl 解码x509Certificate

    最近项目需要添加解码x509Certificate功能,可以使用openssl或者mbedtls库.对这两个库的使用总结一下. 一 Openssl解码x509 Certificate 1. 初始化   ...