直观地说,多态就是“一个对象,多种形态 ”。比如观世音菩萨就有多种形态——

每个人都有多种形态——


具体地讲,多态是指“同一个对象、同一个方法(函数),表现出不同的行为”。

在代码层面表现为:父类对象指向子类实例;父类对象 调用(多种)子类方法。比如:

List lst; // lst以List的形式定义
lst = new ArrayList();// 实例化的时候却是子类对象
lst = new LinkedList(); // 可以是不同的子类对象

底层技术:后期绑定(动态绑定/运行时绑定),根据运行时期对象实例来动态判断要调用的方法。


示例:开车

一般考驾照是C1驾照,可以开多种小型汽车:



现定义一个汽车类,两个子类分别是“小货车”、“三蹦子”。

主类“驾照”类中编写main方法,可以分别创建两种子类的车对象,并分别调用其"驾驶()"方法。代码如下——

public class 驾照 {
public static void main(String[] args) {
小货车 b = new 小货车();
b.行驶();
三蹦子 c = new 三蹦子();
c.行驶();
}
}
class 汽车 {
public void 行驶() {
System.out.println("启动理论");
}
}
class 小货车 extends 汽车 {
public void 行驶() {
System.out.println("小货车");
}
}
class 三蹦子 extends 汽车 {
public void 行驶() {
System.out.println("三蹦子");
}
}

上例中定义了两个对象,分别是b和c,可以理解为开小货车需要先了解小货车,开三蹦子需要先了解三蹦子,有点麻烦。

能不能一照到手,随便开车?

	public static void main(String[] args) {
// 小货车 b = new 小货车();
// b.行驶();
// 三蹦子 c = new 三蹦子();
// c.行驶();
汽车 c;
c = new 小货车();
c.行驶();
c = new 三蹦子();
c.行驶();
}

修改后的代码只声明了一个对象c,属于父类的实例对象,可以分别实例化为子类,虽然方法调用都是“c.行驶()”,但输出的结果是不同的。这就是多态。

向上转型,向下转型

以父类的名义实例化一个子类对象,属于向上转型。

向上转型,是自动提升的。因为上层更抽象,范围更大,没什么问题;

小货车也是车,用更抽象的上层代表下层没有问题。

但是如果说车是小货车,就不一定对了,这个属于向下转型。

向下转型,需要强制转换。因为下层更具体,可能有父类未定义的方法,转型不一定安全。

下面的代码演示了使用括号进行强制的向下转型——

public class 多态转型 {
public static void main(String[] args) {
Animal _animal = null;
Cat _cat = new Cat();
_animal = _cat;// 向上转型(自动提升):猫是动物,没问题
_cat = (Cat) _animal;// 向下转型(强制转换):动物未必都是猫
// ↑↑↑之所以向下转型成功,是因为_animal本就是Cat,属于还原;
// -----------
// 动物有可能不是猫,转型可能出错
_animal = new Dog();
_cat = (Cat) _animal;// ClassCastException
// 即使是单纯的父类实例对象,向下转型也会失败
_animal = new Animal();
_cat = (Cat) _animal;// ClassCastException
}
}
class Animal {
}
class Cat extends Animal {
}
class Dog extends Animal {
}

另一个示例:String类是Object的子类

		String s ="太上老君";
Object o = s;// 向上转型(自动提升)
s = (String)o;// 向下转型(强制转换)

instanceof运算符

用于判断左边的对象是否属于右边的类型(实例、子类实例)。

如果左边对象和右边类没有继承关系,编译会出错。

public class 多态转型 {
public static void main(String[] args) {
Animal _animal = new Cat();
System.out.println(_animal instanceof Cat);
System.out.println(_animal instanceof Animal);
System.out.println(_animal instanceof Dog);
System.out.println(_animal instanceof Object);
// 和String类没有继承关系,编译无法通过
// System.out.println(_animal instanceof String);
// ----------------------
// 先判断,再转换
if (_animal instanceof Cat) {
Cat _cat = (Cat) _animal;
System.out.println(_cat.getClass());
}
}
}
class Animal {
}
class Cat extends Animal {
}
class Dog extends Animal {
}

结果:

true
true
false
true
class Cat

Java基础教程——多态的更多相关文章

  1. Java基础教程(18)--继承

    一.继承的概念   继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...

  2. Java基础教程:泛型基础

    Java基础教程:泛型基础 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚 ...

  3. Java基础教程:面向对象编程[2]

    Java基础教程:面向对象编程[2] 内容大纲 访问修饰符 四种访问修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default ...

  4. Java基础十一--多态

    Java基础十一--多态 一.多态定义 简单说:就是一个对象对应着不同类型. 多态在代码中的体现: 父类或者接口的引用指向其子类的对象. /* 对象的多态性. class 动物 {} class 猫 ...

  5. Java基础教程(12)--深入理解类

    一.方法的返回值   当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...

  6. Java基础教程:注解

    Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...

  7. Java基础教程:网络编程

    Java基础教程:网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个s ...

  8. Java基础教程(5)--变量

    一.变量 1.变量的定义   正如上一篇教程<Java基础教程(4)--面向对象概念>中介绍的那样,对象将它的状态存在域中.但是你可能仍然有一些疑问,例如:命名一个域的规则和惯例是什么?除 ...

  9. Java基础教程:Lambda表达式

    Java基础教程:Lambda表达式 本文部分内容引用自OneAPM:http://blog.oneapm.com/apm-tech/226.html 引入Lambda Java 是一流的面向对象语言 ...

随机推荐

  1. python构造函数和析构函数

    构造函数和析构函数 关注公众号"轻松学编程"了解更多. 1.构造方法的使用 ​ 很多类都倾向于将对象创建为有初始化状态.因此类可以定义一个名为__init__()的特殊方法(构造方 ...

  2. Flask常用扩展(Extentions)

    Flask常用扩展(Extentions) 官网;http://flask.pocoo.org/extensions/ 1.Flask-Script ​ 说明: 一个flask终端运行的解析器 安装: ...

  3. 1.深入Istio:Sidecar自动注入如何实现的?

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的Istio源码是 release 1.5. 这篇文章打算讲一下sidecar, ...

  4. node转发请求 .csv格式文件下载 中文乱码问题 + 文件上传笔记

    用户无法直接访问后台接口 需要node端转发请求 并将数据以.csv文件格式生成以供客户端下载. 很不幸出现了中文乱码的问题 挖了各种坟帖,下了各种依赖包,csv.json2csv.bufferHel ...

  5. Thinkphp3.2 cms之文章模块

    二.文章模块 <?php namespace Admin\Controller; use Think\Controller; class NewController extends Common ...

  6. git clone下载速度慢的解决方案

    由于自己碰到git clone速度慢的问题,查询后发现有一个很好用的方法 首先获得你git clone的原格式,例如: git clone https://github.com/graykode/nl ...

  7. lambda表达式的distinct去重

    天真的我最开始以为可以写成list.distinct(x=>x.name);以为这样就可以按照name去重了,结果是不行的.这里记录下正确的用法. 1.这里是针对int集合  可以满足 #reg ...

  8. layuiu按钮

    1.关于layui图标 唯一要提的是这是一个矢量图标 因此可以像对待文字一样加上style = font-size  以及color属性 eg: <i class="layui-ico ...

  9. 八位“Booth二位乘算法”乘法器

    目录 八位"Booth二位乘算法"乘法器 原理 补码乘法器 Booth一位乘 Booth二位乘 设计思路 减法变加法 vivado特性 设计文件 综合电路 测试文件 仿真波形 八位 ...

  10. RocketMQ4.x安装部署

    1.下载安装包:https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.2.0/rocketmq-all-4.2.0-bin-release.zip ...