多态:事物的多种形态。即:
不同的对象收到相同的消息,产生不同的结果。
相同的对象收到不同的消息,产生不同的结果。
比如:
张三收到一部手机,会打游戏
李四收到一部手机,会发微信
王五收到一部手机,会听歌曲
赵六收到一部手机,会看电影
即,不同的人收到相同的手机,产生不同的玩法,就是不同的对象收到相同的消息,产生不同的结果。
因此说,手机这个事物具有多种形态,叫多态。
比如:
张三接到领导的电话,电话里说,小张……….
张三接到老婆的电话,电话里说,老公……….
张三接到父母的电话,电话里说,儿子……….
张三接到朋友的电话,电话里说,哥们……….
即,相同的人收到不用的消息,产生不同的称呼,就是相同的对象收到不同的消息,产生不同的结果。
因此说,张三这个人具有多种形态,叫多态。
多态如何用代码一步步实现的:
- 提高代码的复用性和扩展性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Animal{ void sing(){ System.out.println("唱歌"); } class Cat extends Animal{ void sing(){ System.out.println("喵喵的唱歌"); } } class Dog extends Animal{ void sing(){ System.out.println("汪汪的唱歌"); } } public class duotai{ public static void main(String[] args){ Cat c1=new Cat(); c1.sing(); Cat c2=new Cat(); c2.sing(); Cat c3=new Cat(); c3.sing();
Dog d1=new Dog(); d1.sing(); Dog d2=new Dog(); d2.sing(); Dog d3=new class Animal{ void sing(){ System.out.println("唱歌"); } class Cat extends Animal{ void sing(){ System.out.println("喵喵的唱歌"); } } class Dog extends Animal{ void sing(){ System.out.println("汪汪的唱歌"); } } public class duotai{ public static void main(String[] args){ Cat c1=new Cat(); c1.sing(); Cat c2=new Cat(); c2.sing(); Cat c3=new Cat(); c3.sing();
Dog d1=new Dog(); d1.sing(); Dog d2=new Dog(); d2.sing(); Dog d3=new Dog(); d3.sing(); } }
|
我们可以看到,每new出一个对象,就需要去调用方法,很麻烦,我们可以写一个函数,进行传参,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class duotai{ public static void main(String[] args){ Cat c1=new Cat(); Cat c2=new Cat(); Cat c3=new Cat(); function(c1); function(c2); function(c3); Dog d1=new Dog(); Dog d2=new Dog(); Dog d3=new Dog(); function(d1); function(d2); function(d3); public static void function(Cat mao){ mao.sing();} public static void function(Dog gou){ |
- 多态:上面虽然提高了代码的复用性,但还是麻烦,因为每new一个类对象,就需要写一个函数,因此可以这样写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class mlx{ public static void main(String[] args){ Cat c1=new Cat(); Cat c2=new Cat(); Cat c3=new Cat(); function(c1); function(c2); function(c3);
Dog d1=new Dog(); Dog d2=new Dog(); Dog d3=new Dog(); function(d1); function(d2); function(d3); } static void function(Animal a){ a.sing(); }
|
多态成员变量的特点(原理):
编译时,参阅的是引用型变量所属的类中是否有调用的方法;
运行时,参阅的是对象所属类中是否有调用的方法;
意思是,编译时是向上转型,看父类中是否有调用的方法,运行时,是看传进来的对象有没有方法可以重写。
多态的使用
多态的前提:
- 类与类之间必须存在关系,可以是继承关系,也可以是实现关系;
- 父类中一定要有sing()方法,因为向上转型,只能访问父类的方法,如果父类中没有该方法,就报错了;
- 必须要有重写,否则多态没有意义更不能实现多态了,因为正常向上转型后只能访问父类成员,
如果方法没有重写,就输出“唱歌”了,有重写才能输出自己的sing()方法,喵喵或旺旺的唱;
- 多态=向上转型+重写;
多态的弊端:
- 只能用父类的引用,访问到父类的成员,再看是否有重写;
最后说明:主函数中如果定义方法,一定要设置static静态,我们知道当建立这篇java文档时,主函数类就已经存在了,因此在主函数中的写的方法要加静态,静态是伴随着类的存在而存在,如果不加,这个方法就访问不到了,必须让方法和主函数一起存在。
1 2 3
| static void functionstatic void function(Animal a){ a.sing(); }
|
多态中的向下转型:
如下,因为多态只能看到父类成员,所以如果子类成员中有非重写的方法,就访问不到了,可以使用向下转型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Dog extends Animal{ void sing(){ System.out.println("汪汪的唱歌"); } void fangfa(){ System.out.println("多管闲事"); } } public class duotai{ public static void main(String[] args){ Dog d1=new Dog(); function(d1); } static void function(Animal a){ a.sing(); Dog d=(Dog)a; |
提示:如果不是特殊需要,也没必要在多态中向下转型访问非重写方法,在上面d1.fangfa(),单独调用就ok了,可操性也很大。因为在多态中向下转型反而要和重写方法一起输出,如果不想一起输出就麻烦了,况且如果只需要访问非重写方法,更没必要使用多态了,向上又向下来回转型,反而麻烦了。