标签:
Java面向对象3个基本特征:继承、封装和多态;多态主要体现在重载和重写;
1、静态分派
静态分派与重载有关,虚拟机在重载时是通过参数的静态类型,而不是运行时的实际类型作为判定依据的;静态类型在编译期是可知的;
1)基本类型
以char为例,按照char>int>long>double>float>double>Character>Serializable>Object>...(变长参数,将其视为一个数组元素)
变长参数的重载优先级最低
(注意char到byte或short之间的转换时不安全的)
2)引用类型:则需要根据继承关系进行匹配,注意只跟其编译时类型即静态类型相关
2、动态分派
动态分派与重写(Override)相关
3、示例
1)静态分派
class A {
}
class B extends A {
}
class C extends A {
}
class D extends B implements E, F {
}
interface E {
}
interface F {
}
public class Main1 extends A {
public void test(A a) {
System.out.println("A");
}
public void test(B b) {
System.out.println("B");
}
public void test(C c) {
System.out.println("C");
}
// 填上下面的方法,D转化为父类进行匹配,转化为B,E,F等效,无法找到最优匹配,故会编译报错
// public void test(E e)
// {
// System.out.println("E");
// }
public static void main(String[] args) {
A aa = new A();
A ab = new B();
A ac = new C();
B b = new B();
B bd = new D();
D d = new D();
// C ca = (C) new A();//此编译时会发生错误
C ca = new C();
/* 根据静态分配,重载只与其静态类型相关,若无对应类型,则执行隐式转换进行匹配 */
Main1 main1 = new Main1();
main1.test(aa);// 输出A
main1.test(ab);// 输出A
main1.test(ac);// 输出A
main1.test(b); // 输出B
main1.test(bd);// 输出B
main1.test(ca);// 输出C
main1.test(d); // 输出B
}
}
javap解析结果:
2)动态分派:与动态类型相关
class A {
public void test() {
System.out.println("A");
}
}
class B extends A {
public void test() {
System.out.println("B");
}
}
class C extends A {
public void test() {
System.out.println("C");
}
}
public class Main1 extends A {
public static void main(String[] args) {
A aa = new A();
A ab = new B();
A ac = new C();
B b = new B();
C ca = new C();
//输出:A,B,C,B,C
aa.test();
ab.test();
ac.test();
b.test();
ca.test();
}
}
invokevirtual(调用实例方法)指令执行的第一步就是在运行期确定接收者的实际类型,根据实际类型进行方法调用;
4、单分派与多分派:Java是一门静态多分派,动态单分派的语言;
标签:
原文地址:http://blog.csdn.net/woliuyunyicai/article/details/45008169