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

每个人都有多种形态——


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

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

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. Albert学习记录

    albert相对BERT而言主要有三个改进方向: 1.对Embedding因式分解 在BERT中,词向量维度E和隐层维度H是相等的.而词嵌入学习的是单词与上下文无关的表示,而隐层则是学习与上下文相关的 ...

  2. 关于“Cannot resolve table 'user'”报错的问题解决

    springboot+vue建立映射时,后端引用@Table(name="user") 来对应表名 user,但引用后报错"Cannot resolve table 'u ...

  3. 【转】Key Presses

    FROM:http://lazyfoo.net/tutorials/SDL/04_key_presses/index.php Key Presses Last Updated 6/11/19 Xing ...

  4. oracle ql/sql 相关语法解析

    这篇文章主要介绍了Oracle中游标Cursor基本用法详解,还是比较全面的,具有一定参考价值,需要的朋友可以了解下.   查询 SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELE ...

  5. python进程间共享数值、字典、列表变量

    ##python进程间共享数值.字典.列表变量 关注公众号"轻松学编程"了解更多. import multiprocessing def worker(num, mgr_dict, ...

  6. 机器学习之K均值算法(K-means)聚类

    K均值算法(K-means)聚类 [关键词]K个种子,均值 一.K-means算法原理 聚类的概念:一种无监督的学习,事先不知道类别,自动将相似的对象归到同一个簇中. K-Means算法是一种聚类分析 ...

  7. 常用-DNS

    1.1.1.1 cloudflare 1.0.0.1 119.29.29.29 腾讯 114.114.114.114 114.114.115.115 114.114.114.119财务 114.114 ...

  8. DM的SQL优化入门笔记

    1.查看执行计划EXPLAIN SELECT A.C1+1,B.D2 FROM T1 A, T2 B WHERE A.C1 = B.D1; 2.执行计划: 1 #NSET2: [0, 16, 9] 2 ...

  9. 【SpringBoot】11.Springboot整合SpringMVC+Mybatis(上)

    Springboot整合SpringMVC+Mybatis 需求分析:通过使用Springboot+SpringMVC+Mybatis 整合实现一个对数据库表users表的CRUD操作. 1.创建项目 ...

  10. ps怎么做发光字体效果 ps中最简单的发光字教程

    ps中最简单的发光字教程 我们先用[文字工具]输入文字(比如:发光效果),字体填充为白色,如图所示. 我们选中文字的图层,点击[FX]找到[外发光],如图所示. 接着,我们在外发光里面把颜色设置为紫色 ...