如何从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:就这样吧~~~