多态:所谓多态,就是父类型的引用可以指向子类型的对象,或者接口类型的引用可以指向实现该接口的类的实例。关于接口与实现的类之间强制类型转换方式与父和子之间的强完全一样。
代码:源于张龙老师的视频
关于多态学习的代码:
Animal.java
package cn.sisy.polymorphism; public class Animal { public void sing(){ System.out.println("Animal is singing"); } public String name = "小动物"; }
Cat.java
package cn.sisy.polymorphism; public class Cat extends Animal{ public void sing(){ System.out.println("Cat is singing"); } }
PolyTest02:主要说明向上类型转换和向下类型转换,向上转型不需显示指定,向下转型必须强制转换。
package cn.sisy.polymorphism; public class PolyTest02 { public static void main(String[] args) { //向上类型转换---子类转换为父类 Cat cat = new Cat(); Animal animal = cat; cat.sing(); //向下类型转换---父类转换为子类 //必须使用强制类型转换 Animal a = new Cat(); Cat c1 = (Cat) a; c1.sing(); //以下的转换可以吗? // cn.sisy.base.Animal cannot be cast to cn.sisy.base.Cat Animal b = new Animal(); Cat c2 = (Cat)b; } }
程序运行结果 :
Cat is singing
Cat is singing
Exception in thread "main" java.lang.ClassCastException: cn.sisy.polymorphism.Animal cannot be cast to cn.sisy.polymorphism.Cat
at cn.sisy.polymorphism.PolyTest02.main(PolyTest02.java:17)
------------------------------------------------------------------------------
下面我们为Cat方法增加一些自己的方法和属性
Cat.java
package cn.sisy.polymorphism; public class Cat extends Animal{ public void sing(){ System.out.println("Cat is singing"); } public void voice(){ System.out.println("喵喵~~"); } public String name = "小花猫"; }
PolyTest03.java
package cn.sisy.polymorphism; public class PolyTest03 { public static void main(String[] args) { Animal animal = new Cat(); //以下的语句编译不能通过,因为Animal类中并没有定义voice方法 //animal.voice(); System.out.println(animal.name); //为了调用子类特有的方法,有时候需要进行强制类型转换 Cat cat = (Cat)animal; cat.voice(); System.out.println(cat.name); } }
程序的运行结果:
小动物
喵喵~~
小花猫
以上的结果没有体现出属性的多态;为了调用子类特有的方法,需要进行强制类型转换 。
-------------------------------------------------------------------------
PolyTest4.java 这个例子为了说明多态是一种运行时的行为
package cn.sisy.polymorphism; /* * 此类为了说明Java的多态是一种运行时的行为 * 因为运行之前a根本不知道将会指向哪种引用, * 这种情况也称为dynamically bound */ public class PolyTest4{ public static void main(String[] args){ A a = null; if(args[0].equals("1")){ a = new B(); } else if(args[0].equals("2")){ a = new C(); } else if(args[0].equals("3")){ a = new D(); } a.method(); } } class A{ public void method(){ System.out.println("A"); } } class B extends A{ public void method(){ System.out.println("B"); } } class C extends A{ public void method(){ System.out.println("C"); } } class D extends A{ public void method(){ System.out.println("D"); } }
用 java PolyTest4 2执行程序时将会输出:
C
----------------------------------------------------------------------------------
以下的程序说明了多态在实际开发中应该如何应用:
class Car{ public void run(){ System.out.println("car is running"); } } class BMW extends Car{ public void run(){ System.out.println("BMW is running"); } } class QQ extends Car{ public void run(){ System.out.println("QQ is running"); } }
public class PolyTest5{ public void run(BMW bmw) { bmw.run(); } public void run(QQ qq) { qq.run(); } public static void main(String[] args){ PolyTest5 test = new PolyTest5(); BMW bmw = new BMW(); test.run(bmw); QQ qq = new QQ(); test.run(qq); } }
通过以上的程序我们会发现,如何我们把实际存在的车型都写出来,那么PolyTest5.java这个程序将会十分拥挤,那我们是不是可以用已经学到的多态的知识加以改进呢?请看下面的程序。
public class PolyTest5{ public void run(Car car){ car.run(); } public static void main(String[] args){ PolyTest5 test = new PolyTest5(); Car car = new BMW(); test.run(car); QQ qq = new QQ(); test.run(qq);//此处应用了自动向上转型,所以子类对象都是父类对象 } }
上面的程序是不是改进很多呢。。。只需一个方法。。。。