理解Java多态
多态又称Polymophism,poly意思为多,polymophism即多种形态的意思。一种类型引用因为指向不同的子类,表现出不同的形态,使用不同的方法。
什么是多态
多态建议我们编码时使用common interface(公共接口)而不是concrete implementation(具体实现)。如果我们依赖具体实现来编码,则当我们需要增加common interface的新的实现时,我们需要复制和改变已有代码。程序的可扩展性大大降低。
StackOverflow上关于什么是多态的一个例子很容易记忆。
public abstract class Human{
...
public abstract void goPee();
}
/* 抽象方法goPee()对于Human没有实现,它只对男女这两个子类有具体的不同的实现。
Human也是一个抽象类,因为人只有男或女这两个类,不能创建一个既不是男也不是女的Human。
所以我们通过使用抽象类延迟了实现。*/
public class Female extends Human{
...
@Override
public void goPee(){
System.out.println("Sit Down");
}
}
public class Female extends Human{
...
@Override
public void goPee(){
System.out.println("Sit Down");
}
}
//创建一组人要去尿尿
public static void main(String[] args){
ArrayList<Human> group = new ArrayList<Human>();
group.add(new Male());
group.add(new Female());
// ... add more...
// tell the class to take a pee break
for (Human person : group) person.goPee();
}
运行结果:
Stand Up
Sit Down
...
Java如何实现多态
Java支持实现多态的三个必要条件:继承(inheritance),重写(override),向上转型(upcasting)
继承:
java只支持单继承,即子类和超类之间的关系是“Is-a”的关系。
重写:
父类中的方法会原封不动地被子类继承拥有,但如果子类想做一定的修改,就需要采用方法的重写。父类中的某方法如果与子类中的方法有相同的名称和参数,则该方法被重写。
如果需要在子类中使用被覆盖的父类方法,则可使用super()关键字。子类函数的访问修饰权限不能少于父类。(试想如果一个父类中的方法为public,而在子类中重写为private,则父类类型的引用变量不能调用子类实例对象的方法,导致出错。)
向上转型:
形象化理解即为超类实际上是子类的子集,因为超类的成员都是子类的成员,所以类似Animal cat = new Cat();这样的向上转型是安全的,因为父类引用变量可以操作的成员一定在子类中。与此相反的向下转型则需要使用Instanceof来判断是否安全。
动态绑定:
动态绑定又称后期绑定,是指编译器在编译期间不知道要调用哪个方法,直到运行时才能确定。方法的动态绑定是基于实例对象类型,而不是对象引用的类型。基本上实例方法都在运行时绑定,而private方法,static方法,final方法都在编译时期绑定,称为静态绑定或后期绑定。这也是为什么private, static, final方法不允许重写。
当超类对象引用变量引用子类的对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的成员方法必须在超类中定义过,也就是说被子类覆盖的方法。
总结:
以上机制允许java运行期间执行某个类的成员方法,而不是编码时期声明类型决定。(Method overriding allows java invoke method based on a perticular object at run-time instead of declared type while coding.)
例子:
public class TradingSystem{
public String getDescription(){
return "electronic trading system";
}
}
public class DirectMarketAccessSystem extends TradingSystem{
public String getDescription(){
return "direct market access system";
}
}
public class CommodityTradingSystem extends TradingSystem{
public String getDescription(){
return "Futures trading system";
}
}
何时使用多态:
- 使用超类作为方法参数,可以在方法内调用不同类的成员方法。
public void showDescription(TradingSystem tradingSystem){
tradingSystem.description();
} - 使用超类声明变量,可以接收Factory method的返回值。
String systemName = Configuration.getSystemName();
TradingSystem system = TradingSystemFactory.getSystem(systemName); - 使用超类作为返回值
public TradingSystem getSystem(String name){
//code to return appropriate implementation
}
这篇文章提供了一个很好的例子
对于Java实现讲解的好文章
参考文章:
What is polymorphism in Java? Method overloading or overriding?
Java 重写(Override)与重载(Overload)
理解Java多态的更多相关文章
- 深入理解java多态没有烤山药的存在,java就不香了吗?
目录 1. 从吃烤山药重新认识多态 2. 多态前提条件[重点] 3. 多态的体现 4. 多态动态绑定与静态绑定 5. 多态特性的虚方法(virtual) 7. 向上转型 8. 向下转型 9. 向上向下 ...
- 深入理解Java多态机制
从字节码层面来看,Java中的所有方法调用,最终无外乎转换为如下几条调用指令. invokestatic: 调用静态方法. invokespecial: 调用实例构造器<init>方法,私 ...
- 深入理解JAVA多态原理
之前一直知道多态是什么东西,平时敲代码也经常用到多态,但一直没有真正了解多态底层的运行机制到底是怎么样的,这两天才研究明白点,特地写下来,跟各位同学一起进步,同时也希望各位大神指导和指正. 多态的概念 ...
- 【转】深入理解Java多态原理
之前一直知道多态是什么东西,平时敲代码也经常用到多态,但一直没有真正了解多态底层的运行机制到底是怎么样的,这两天才研究明白点,特地写下来,跟各位同学一起进步,同时也希望各位大神指导和指正. 多态的概念 ...
- 巩固java(五)----通过实例理解java多态
package duotai; class A{ public String show(){ return "A"; } } class B extends A{ public S ...
- java提高篇(四)-----理解java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- java提高篇(三)-----理解java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- (转)java提高篇(四)-----理解java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- 关于java多态的理解
要理解多态,就必须有一个大的理解方向,不然很容易绕进去. 首先知道多态的释义:多态性是指一个名词可以有多种语义. 对于java的多态性学习者来说,就是必须要知道多个同名方法在不同情况下的使用规则. j ...
随机推荐
- ZJUTACM(hd1259)
ZJUTACM 点我 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- How Many Tables(并查集)
How Many Tables Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- C语言--关键字、标识(zhi)符、注释
一.关键字 1. 关键字 是C语言中提供的有特殊含义的符号,同时也叫做保留字,在C语言中关键字一共有32个,它们分别被赋予了特殊的含义.如:main.int.struct等等. 2. 关键字的特征 1 ...
- Android: ScrollView监听滑动到顶端和底端
在项目中需要监听ScrollView滑动到顶端和底端的时候以实现自己的ScrollView,那么怎样去监听呢?今天查看了一下ScrollView的源码,找到了一种方法.先看一下源码中的overScro ...
- MVC WebApi 用户验证 (2)
构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(66)-MVC WebApi 用户验证 (2) 前言: 构建ASP.NET MVC5+EF6+E ...
- Gartner Publishes 2014 Magic Quadrant for SIEM and Critical Capabilities for SIEM Reports
http://securityintelligence.com/gartner-2014-magic-quadrant-siem-security/#.SzNnhshk https://www.net ...
- hdu 1698 Just a Hook_线段树
题意:给你个n,表示区间[1,n],价值初始为1,给你m段区间和价值,更新区间,区间价值以最后更新为准,问更新后区间价值总和为多少 思路:两种方法,可以先存下来,倒过来更新,一更新节点马上跳出,比较快 ...
- la 3942 Rember_前缀树
#include <iostream> #include<cstdio> #include<cstring> using namespace std; #defin ...
- 使用xmanager 远程redhat6.3
之前装过一次,特别麻烦,装上只有远程还卡卡的,这次按照教程居然装的灰常顺利,不符合我bug体质的特性,一定要记下来啊~~~ 1.先关闭防火墙 # service iptables stop #chkc ...
- HDU 5785 Interesting
题目: 大概说给一个字符串,找到其所有子串[i...k]满足它是由两个回文串拼成的,求Σi*k. 分析: 用val[1][i]表示以i结尾的回文串的起始位置的和val[0][i]表示以i起始的回文串的 ...