如何从Java多态性举办飘渺之旅呢? 我们用例子来观光。
朵星人A:人类,是一个很奇妙的物种。 朵星人B:他们仿佛分为两种,嗯 先生,以及美男? 朵星人C:对,更年青的有叫 美少女的。 朵星人D:他们之间怎么打号召的?我们问问AI(编译器大佬)吧。。 朵星人A:可以有。启动吧~
第一次启动:
/**
* 编译时多态
*
* @author Sven Augustus
*/
public class StaticTest {
static abstract class Human {
}
static class Man extends StaticTest.Human {
}
static class Woman extends StaticTest.Human {
}
static class Girl extends StaticTest.Woman {
}
public void sayHello(Object guy) {
System.out.println("你...");
}
public void sayHello(Human guy) {
System.out.println("你好");
}
public void sayHello(Man guy) {
System.out.println("您好,先生");
}
public void sayHello(Woman guy) {
System.out.println("您好,美男");
}
public void sayHello(Girl guy) {
System.out.println("您好,美少女");
}
public static void main(String[] args) {
StaticTest test = new StaticTest();
StaticTest.Human manAsGuy = new StaticTest.Man();
StaticTest.Human womanAsGuy = new StaticTest.Woman();
StaticTest.Woman girlAsWoman = new StaticTest.Girl();
test.sayHello(manAsGuy);
test.sayHello(womanAsGuy);
test.sayHello(girlAsWoman);
}
}
输出:

编译器大佬汇报了他们谜底。
朵星人众人:纳尼,他们叫的好奇怪啊?好没规矩啊,没“您”。为毛呢??尚有最后一个显着是美少女,你怎么叫美男啊?! 编译器大佬:你们盛情思吗,你们都标为人类或美男。 我怎么知道他们详细是先生照旧美男,亦或是美少女啊!!!所以我就只知道这么多。
StaticTest.Human manAsGuy = new StaticTest.Man();
test.sayHello(manAsGuy);
从这里,Human 称为 声明范例(也有叫静态范例) ,Man 称为 实际范例。
很清楚,此刻要害在于 manAsGuy 作为 参数。
在编译阶段,编译器就可以按照 参数 的 声明范例(或叫静态范例) 抉择利用哪个重载版本的要领。
朵星人A:说的好有原理,软件开发,我们让他们本身称号吧。 朵星人B:可以有。 朵星人C:附和。 朵星人D:不会有问题吧? 朵星人A:不会的。就这样吧~~~
第二次启动:
/**
* 运行时多态
*
* @author Sven Augustus
*/
public class DynamicTest {
static abstract class Human {
public void sayHello() {
System.out.println("你好");
}
}
static class Man extends DynamicTest.Human {
public void sayHello() {
System.out.println("您好,我是Y先生");
}
}
static class Woman extends DynamicTest.Human {
public void sayHello() {
System.out.println("您好,我是X美男");
}
}
public static void main(String[] args) {
DynamicTest.Human manAsGuy = new DynamicTest.Man();// 注释1
DynamicTest.Human womanAsGuy = new DynamicTest.Woman();
manAsGuy.sayHello();
womanAsGuy.sayHello();
}
}
输出:

编译器大佬仿佛去休息了,交给社会JVM答复问题。
DynamicTest.Human manAsGuy = new DynamicTest.Man();// 注释1 manAsGuy.sayHello();
这里与上个例子差异的是,软件开发,manAsGuy不作为 参数,是作为引用变量 去 挪用要领。
这时候,编译器只知道 引用变量manAsGuy的 静态范例,对付实际范例 就无能为力。因此在运行时由JVM要领表动态绑定。
我们发明,
引用变量挪用要领 的时候,抉择去挪用哪个要领,是由 实际范例 在运行时确认挪用哪个要领,而不是 声明范例(或叫静态范例)。
呵呵,虽然这个表明照旧较量委曲。我们继承。
朵星人A:咦,他们太客套了,都“您好”,还首先先容本身,好不自持啊。 朵星人B:地球人是这样的吗?? 朵星人C:是这样的。他们不知道对方是谁,只知道本身是谁的时候是这样的。 朵星人D:仿佛不是啊。 朵星人A:那你说是奈何的? 朵星人D:他们需要知道对方是谁啊! 朵星人B:有原理、 朵星人C:附和。 朵星人A:就这样吧~~~