Java---08---多态性
多态:
可以理解为事物存在的多种体现形态。
人有什么形态,男人、女人。
多态是子类对象在做着变化。
猫 x = new 猫 ();
动物 x = new 猫();
这就是一个对象具有多种形态。X是猫类型,同时也是“动物”类型。
类型提升 : 把猫提升为动物类型。向上转型
1.多态的体现
父类的引用指向了自己的子类对象
父类的引用也可以接收自己的子类对象
2.多态的前提
必须是类与类之间有关系,要么继承,要么实现
存在覆盖
3.多态的好处
提高了程序的扩展性
4.多态的弊端
提高扩展性,但是只能使用父类的引用访问父类中的成员
静态绑定和动态绑定:
静态绑定:编译时期就可以确定所调用的方法。Java中 只有 final、static、private和构造方法属于静态绑定。
动态绑定:运行时才可以确定所调用的方法。
重载和覆盖:
方法重载:用在用一个类中,所谓的重载是 方法名相同,但是返回值和参数列表可以不同。在程序运行时,编译器会根据传递过来的参数自动选择适合这种参数类型的方法。
方法覆盖:用在继承中。父类的方法在子类中出现,且是一模一样的(包括返回值和参数列表)。
abstract class Animal { abstract void eat (); } class Cat extends Animal { public void eat () { System.out.println("Cat.eat()"); } } class Dog extends Animal { public void eat() { System.out.println("Dog.eat()"); } } public class Practice { public static void main (String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); cat.eat(); dog.eat(); Animal c = new Cat();//类型提升 向上转型 c.eat(); Animal d = new Dog(); d.eat(); } }
Animal c = new Cat(); c.eat(); c.CatchMoushe();
编译失败:The method CatchMoushe() is undefined for the type Animal
将子类向上转型为父类类型后,该对象所能使用的方法只能是父类拥有的。
而运行时所调用的方法则是子类对象自己的。
如何实现cat的特有方法?
向下转型。
Cat a = (Cat)c;
判断某一类型的引用是否是这个类型 :instanceof
if ( c instanceof Cat ) { ((Cat) c).CatchMoushe(); }
非静态在多态中成员函数的特点:
编译时期:参阅引用型变量所属的类中是否有调用的方法
如果有编译通过,没有则失败
运行时期:参阅对象所属的类中是否有调用的方法
非静态成员函数在多态调用时,编译看左边,运行看右边
就是说:子类中有的,就调用子类的方法,没有的就去父类中找。如果还没有,则是不会编译通过的。
在多态中成员变量的特点:编译运行都参考左边。
class Fu { int num = 10; } class Zi extends Fu { int num = 20; } class Main { public static void main (String[] args) { Fu f = new Zi(); Zi z = new Zi(); System.out.println(f.num+"\n"+z.num); } }
输出的结果是:
10
20
静态成员函数的特点:参考左边。
class Fu { int num = 10; static void show () { System.out.println("Fu.show()"); } } class Zi extends Fu { int num = 20; static void show () { System.out.println("Zi.show()"); } } class Main { public static void main (String[] args) { Fu f = new Zi(); Zi z = new Zi(); f.show(); z.show(); } }
输出结果:
Fu.show()
Zi.show()
在别人的文章中看到这么一个例子:
class A { public String show(D obj){ return ("A and D"); } public String show(A obj){ return ("A and A"); } } class B extends A{ public String show(B obj){ return ("B and B"); } public String show(A obj){ return ("B and A"); } } class C extends B{} class D extends B{} public class DuoTai { public static void main (String[] args){ A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println(a1.show(b)); // ① System.out.println(a1.show(c)); // ② System.out.println(a1.show(d)); // ③ System.out.println(a2.show(b)); // ④ System.out.println(a2.show(c)); // ⑤ System.out.println(a2.show(d)); // ⑥ System.out.println(b.show(b)); // ⑦ System.out.println(b.show(c)); // ⑧ System.out.println(b.show(d)); // ⑨ } }
输出结果:
/* A and A ① A and A ② A and D ③ B and A ④ B and A ⑤ A and D ⑥ B and B ⑦ B and B ⑧ A and D ⑨ */
这个涉及到了方法调用的优先级问题
优先级由高到低依次是:
this.show(O)、
super.show(O)、
this.show((super)O)、
super.show((super)O)。
举个例子说明一下:
①:a1.show(b);
a1是A类的对象,先是 this.show(O) 调用的方法先去A类中找,传递的参数是b类对象,在A中没有该方法,那么按super.show(O)
来找 ,找A的父类,A没有父类,再接着执行this.show((super)O) 找b类的父类,b类的父类是A,在A类中有该方法、输出。
②:a1.show(c)
还是先到A中找方法,A中没有,找A的父类,A没父类,找C的父类,C的父类是B ,A中还是没有方法,再找A的父类中找B,A没父类
再找B的父类,B的父类是A,A中有该方法,输出。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。