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

每个人都有多种形态——

具体地讲,多态是指“同一个对象、同一个方法(函数),表现出不同的行为”。
在代码层面表现为:父类对象指向子类实例;父类对象 调用(多种)子类方法。比如:
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基础教程——多态的更多相关文章
- Java基础教程(18)--继承
一.继承的概念 继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...
- Java基础教程:泛型基础
Java基础教程:泛型基础 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚 ...
- Java基础教程:面向对象编程[2]
Java基础教程:面向对象编程[2] 内容大纲 访问修饰符 四种访问修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default ...
- Java基础十一--多态
Java基础十一--多态 一.多态定义 简单说:就是一个对象对应着不同类型. 多态在代码中的体现: 父类或者接口的引用指向其子类的对象. /* 对象的多态性. class 动物 {} class 猫 ...
- Java基础教程(12)--深入理解类
一.方法的返回值 当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...
- Java基础教程:注解
Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...
- Java基础教程:网络编程
Java基础教程:网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个s ...
- Java基础教程(5)--变量
一.变量 1.变量的定义 正如上一篇教程<Java基础教程(4)--面向对象概念>中介绍的那样,对象将它的状态存在域中.但是你可能仍然有一些疑问,例如:命名一个域的规则和惯例是什么?除 ...
- Java基础教程:Lambda表达式
Java基础教程:Lambda表达式 本文部分内容引用自OneAPM:http://blog.oneapm.com/apm-tech/226.html 引入Lambda Java 是一流的面向对象语言 ...
随机推荐
- 排名靠前的几个JS框架发展趋势和前景
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://blog.bitsrc.io/top-5-javascript-frameworks ...
- K8S环境快速部署Kafka(K8S外部可访问)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- twoSum问题的核心思想
Two Sum 系列问题在 LeetCode 上有好几道,这篇文章就挑出有代表性的几道,介绍一下这种问题怎么解决. TwoSum I 这个问题的最基本形式是这样:给你一个数组和一个整数 target, ...
- 转载:解密Redis持久化
本文内容来源于Redis作者博文,Redis作者说,他看到的所有针对Redis的讨论中,对Redis持久化的误解是最大的,于是他写了一篇长文来对Redis的持久化进行了系统性的论述.文章非常长,也很值 ...
- 前端之旅一:vscode调试web配置
vscode调试web配置 第一步:安装vscode,并启动(vscode的安装包自行到其官网上下载) 第二步:在vscode上安装chrome插件 第三步:配置,启动调试 配置信息 { // Use ...
- Flink的sink实战之三:cassandra3
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- leetcode45:maximum depth of binary tree
题目描述 求给定二叉树的最大深度, 最大深度是指树的根结点到最远叶子结点的最长路径上结点的数量. Given a binary tree, find its maximum depth. The ma ...
- layui tempalte添加函数
@*超链接action展示*@ <script type="text/html" id="ShowAction"> {{# if(d.DealSta ...
- 设置layui表格cell的内边距
/*设置layui表格cell的内边距*/ .layui-table-cell { height: 50px !important; line-height: 50px !important; }
- jquery DataTable插件使用自定义搜索
$(function () { $("#pk_status").change(function () { valid = $(this).val(); if(valid){ tab ...