多态里更多的语法点
静态多态:重载(Overload)
动态多态:覆盖(Override)
看例程:学习重载和覆盖的花式操作
勿忘初心:程序的执行就是找到要执行的代码,并且知道执行的代码能访问哪些数据,数据从哪里来。多态的核心问题就是:要调用哪个类的
哪个方法,这个方法用到的数据(this 引用)是谁
public class MerchandiseTest {
// TODO 之前重载的时候,参数是用的自定义类型。现在理解了父类和子类的引用赋值关系,重载又多了一层复杂性
public void testMerchandiseOverload(MerchandiseV2 me) {
System.out.println("参数为MerchandiseV2的testMerchandiseOverload 被调用了");
}
public void testMerchandiseOverload(Phone ph) {
System.out.println("参数为Phone的testMerchandiseOverload 被调用了");
}
public void testMerchandiseOverload(ShellColorChangePhone shellColorChangePhone) {
System.out.println("参数为ShellColorChangePhone的testMerchandiseOverload 被调用了");
}
public void testMerchandiseOverload(String str) {
System.out.println("参数为String的testMerchandiseOverload 被调用了");
}
public void testMerchandiseOverloadNotExactlyMatchType(MerchandiseV2 me) {
System.out.println("参数为MerchandiseV2的testMerchandiseOverloadNotExactlyMatchType 被调用了");
}
// public void testMerchandiseOverloadNotExactlyMatchType(Phone ph) {
// System.out.println("参数为Phone的testMerchandiseOverloadNotExactlyMatchType 被调用了");
// }
public void testMerchandiseOverloadNotExactlyMatchType(String str) {
System.out.println("参数为String的testMerchandiseOverloadNotExactlyMatchType 被调用了");
}
public class OverloadAndOverrideTestAppMain {
public static void main(String[] args) {
LittleSuperMarket superMarket = new LittleSuperMarket("大卖场",
"世纪大道1号", 500, 600, 100);
MerchandiseV2 m = superMarket.getMerchandiseOf(100);
// TODO 让重载的归重载,剩下的是覆盖的舞台
// TODO 重载决定了要调用参数为int的方法,这个方法要在m指向的对象上执行
// TODO 好巧不巧,这个对象老复杂了,是个ShellColorChangePhone对象,好戏上演了
// TODO, 分别用true, 1, 3, 6做参数,运行结果是什么,为什么?
m.buy(6);
}
}
public class OverloadTestAppMain {
public static void main(String[] args) {
LittleSuperMarket superMarket = new LittleSuperMarket("大卖场",
"世纪大道1号", 500, 600, 100);
MerchandiseV2 m = superMarket.getMerchandiseOf(100);
MerchandiseTest merchandiseTest = new MerchandiseTest();
System.out.println("-----------1-------------");
// TODO 重载调用哪个方法,和参数的引用类型相关,和引用实际指向的类型无关
merchandiseTest.testMerchandiseOverload(m);
merchandiseTest.testMerchandiseOverload((Phone) m);
merchandiseTest.testMerchandiseOverload((ShellColorChangePhone) m);
// TODO 甚至是个null也可以,但是要用强制类型转换,告诉Java这个类型是什么,否则找不到一个唯一的方法去调用
// TODO 重载的参数类型,相同位置,不一定要有继承或者兼容的关系,完全free style
merchandiseTest.testMerchandiseOverload("");
System.out.println("-----------2-------------");
System.out.println();
// >> TODO 引用本身是null没关系,确定调用哪个方法只需要引用的类型。这叫做静态多态。即在编译期就知道该调用哪个方法
m = null;
merchandiseTest.testMerchandiseOverload(m);
merchandiseTest.testMerchandiseOverload((Phone) m);
merchandiseTest.testMerchandiseOverload((ShellColorChangePhone) m);
System.out.println("-----------3-------------");
// >> TODO 如果引用类型没有完全匹配的,则会根据继承关系,沿着参数当前类型,向下撸
merchandiseTest.testMerchandiseOverloadNotExactlyMatchType((ShellColorChangePhone) null);
// >> TODO 重载总结:静态多态,调用的方法和参数实际指向的对象无关,只和引用本身的类型相关。
// >> TODO 因为调用时参数类型是确定的,所以,在编译期间就可以明确的知道哪个方法会被调用。如果有多种可能,则会有编译错误
// >> TODO 如果没有类型完全匹配的候选,则根据类型的继承关系向下撸着找。找到最贴近参数类型的那个方法
// >> TODO 无论是静态方法,还是成员方法,重载寻找方法的顺序是一样的,在这里就不赘述了
// TODO (再提一句多继承,Java没有多继承,是前辈给我们的馈赠。保护了发际线。心疼隔壁CPP的程序员)
}
}
之前重载的时候,参数是用的自定义类型。现在理解了父类和子类的引用赋值关系,重载又多了一层复杂性
让重载的归重载,剩下的是覆盖的舞台
重载决定了要调用参数为int的方法,这个方法要在m指向的对象上执行
重载调用哪个方法,和参数的引用类型相关,和引用实际指向的类型无关
甚至是个null也可以,但是要用强制类型转换,告诉Java这个类型是什么,否则找不到一个唯一的方法去调用
重载的参数类型,相同位置,不一定要有继承或者兼容的关系,完全free style
引用本身是null没关系,确定调用哪个方法只需要引用的类型。这叫做静态多态。即在编译期就知道该调用哪个方法
如果引用类型没有完全匹配的,则会根据继承关系,沿着参数当前类型,向下撸
重载总结:静态多态,调用的方法和参数实际指向的对象无关,只和引用本身的类型相关。
因为调用时参数类型是确定的,所以,在编译期间就可以明确的知道哪个方法会被调用。如果有多种可能,则会有编译错误
如果没有类型完全匹配的候选,则根据类型的继承关系向下撸着找。找到最贴近参数类型的那个方法
无论是静态方法,还是成员方法,重载寻找方法的顺序是一样的,在这里就不赘述了
再提一句多继承,Java没有多继承,是前辈给我们的馈赠。保护了发际线。心疼隔壁CPP的程序员)