1 多态的概述定义:某一类事物的多种存在形态。
伪代码如下:
class 动物{}class 猫 extends 动物{}class 狗 extends 动物{}猫 x = new 猫();动物 y = new 猫();
猫这类事物既具有猫的形态,又具有动物的形态,这就是对象的多态性。换句话说,就是一个对象对应不同的类型。
总结:多态在代码中的体现就是,父类或接口的引用指向其子类的对象,换句话说,就是一个对象两种状态,比如上面的动物 y = new 猫();是不是只有一个对象,但是却有猫和动物的形态。
下面以图来讲解多态。(情节纯属虚构)
2 多态的好处动物
package java009;/** * 2017/9/11 * 说明: */public abstract class Animal { /** * 动物吃饭 */ public abstract void eat();}
猫
package java009;/** * 2017/9/11 * 说明: */public class Cat extends Animal { @Override public void eat() { System.out.print("猫吃鱼"); } public void sleep(){ System.out.print("猫打瞌睡"); }}
狗
package java009;/** * 2017/9/11 * 说明: */public class Dog extends Animal { @Override public void eat() { System.out.print("狗吃肉"); } public void look(){ System.out.print("狗看门"); }}
测试
package java009;/** * 2017/9/11 * 说明: */public class DuoTai { public static void main(String[] args) { Cat c = new Cat(); DuoTai.method(c); Dog d = new Dog(); DuoTai.method(d); } public static void method(Cat c){ c.eat(); } public static void method(Dog d){ d.eat(); }}
点评:貌似上面的代码已经可以实现我们所需要的功能,但是如果此时我们需要增加猪、牛、羊许许多多的动物,哇,太惨,我们在测试类要写很多method的重载方法。很烦,很烦。
package java009;/** * 2017/9/11 * 说明: */public class DuoTai { public static void main(String[] args) { Cat c = new Cat(); DuoTai.method(c); Dog d = new Dog(); DuoTai.method(d); } public static void method(Animal a){ a.eat(); } }
点评:我们通过在method方法中设置method的形参是狗和猫的父类,这样当我们构建对象的时候,无论我们传递什么对象,只要是动物的子类就可以了。
多态的好处:提高了代码的扩展性。
3 多态的弊端和前提多态的弊端:不能使用子类特有的功能。
多态的前提:①有继承或实现关系。②要有方法的重写。
4 多态的转型向上转型:从子到父,父类引用指向子类对象。弊端:不能访问子类特有的功能。好处:限制对子类特有功能的访问。 向下转型:从父到子,父类引用转为子类对象。弊端:可能出出现类转换异常。好处:能对子类特有功能的访问。
示例:向上转型
package java009;/** * 2017/9/11 * 说明: */public class DuoTai { public static void main(String[] args) { Animal a = new Cat(); a.eat(); }}
示例:向下转型
package java009;/** * 2017/9/11 * 说明: */public class DuoTai { public static void main(String[] args) { Animal a = new Cat(); Cat c = (Cat) a; c.eat(); c.sleep(); }}
5 多态的类型判断instanceof 用于判断对象的具体类型,只能用于引用数据类型判断。
示例:
package java009;/** * 2017/9/11 * 说明: */public abstract class Animal { /** * 动物吃饭 */ public abstract void eat();}
package java009;/** * 2017/9/11 * 说明: */public class Cat extends Animal { @Override public void eat() { System.out.print("猫吃鱼"); } public void sleep(){ System.out.print("猫打瞌睡"); }}
package java009;/** * 2017/9/11 * 说明: */public class Dog extends Animal { @Override public void eat() { System.out.print("狗吃肉"); } public void look(){ System.out.print("狗看门"); }}
package java009;/** * 2017/9/11 * 说明: */public class DuoTai { public static void main(String[] args) { method(new Cat()); } public static void method(Animal a){ if(a instanceof Cat){ Cat c = (Cat) a; c.sleep(); c.eat(); }else if(a instanceof Dog){ Dog d = (Dog) a; d.eat(); d.look(); } }}
6 多态的成员变量–了解示例:
package java009;/** * 2017/9/12 * 说明: */class Fu{ int num = 3;}class Zi extends Fu{ int num = 4;}public class Test { public static void main(String[] args) { Zi z = new Zi(); System.out.println(z.num); Fu f = new Zi(); System.out.println(f.num); }}
编译时,参考引用型变量所属的类中是否有调用的成员变量,有,则编译通过,没有,则编译失败。运行时,参考引用型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量。
温馨小提示:实际开发中,不可以这样定义的,以为我们一般会将属性私有化,提供对外的setter和getter方法。7 多态的成员函数示例:
package java009;/** * 2017/9/12 * 说明: */class Fu{ public void show(){ System.out.print("fu"); }}class Zi extends Fu{ public void show(){ System.out.print("zi"); }}public class Test { public static void main(String[] args) { Fu f = new Zi(); f.show(); }}
编译时,参考引用型变量所属的类中是否有调用的函数,有,则编译通过,没有,则编译失败。运行时,参考的是对象所属的类中是否有调用的函数。
8 多态的静态函数示例:
package java009;/** * 2017/9/12 * 说明: */class Fu{ public static void show(){ System.out.print("fu"); }}class Zi extends Fu{ public static void show(){ System.out.print("zi"); }}public class Test { public static void main(String[] args) { Fu f = new Zi(); f.show(); }}
编译时,参考引用型变量所属的类中是否有调用的静态方法。运行时,参考引用型变量所属的类中是否有调用的静态方法。谦受益,满招损。