多态的概念,特点与使用

多态:可以理解为事物存在的多种体现形态

如:人:男人,女人

  动物:猫,狗,鸟

猫这个动物应该是猫类型的:猫 cat = new 猫();

同时猫也是动物的一种:动物 y = new 猫();  动物是猫和狗具体事物抽取出来的父类型,父类型指向了子类对象 

 

1、多态的体现

  父类的引用指向了自己的子类对象

  父类的引用也可以接收自己的子类对象

2、多态的前提

  必须是类与类之间有关系,要么继承,要么实现

  还有一个前提:存在覆盖  

3、多态的好处

  多态的出现大大的提高了程序的扩展性

4、多态的弊端

  虽然提高了扩展性,但是只能使用父类的引用访问父类中的成员

5、多态的应用

6、多态使用的注意事项  

 

看一个关于多态的例子:

 1 abstract class Teacher
 2 {
 3     public abstract void teach();
 4     public void sleep()
 5     {
 6         System.out.println("睡觉");
 7     }
 8 }
 9 class MathTeacher extends Teacher
10 {
11     public void teach()
12     {
13         System.out.println("教数学");
14     }
15 }
16 class ChineseTeacher extends Teacher
17 {
18     public void teach()
19     {
20         System.out.println("教语文");
21     }
22     public void sleep()
23     {
24         System.out.println("睡觉在沙发上");
25     }
26 }
27 //将代码进一步优化,定义一个工具类,这样就不需要实例化每一个老师对象,直接调用工具类,然后把各种类型的Teacher传进去既可
28 class TeachTest
29 {
30     public static void teach(Teacher t)//Teacher t类型是Teacher由于多态可以直接传MathTeacher等
31     {
32         t.teach();
33         t.sleep();
34     }
35 }
36 class Test
37 {
38     public static void main(String[] args)
39     {
40         /*
41         实例化一个新的数学老师
42         Teacher t = new MathTeacher(); 类型提升,向上转型
43         t.sleep();
44         如果想要调用猫的特有方法该怎么做?
45         强制将父类引用转成子类类型,向下转型
46         MathTeacher mt = (MathTeacher)t;
47         mt.teach();  就可以调用数学老师里面的教学方法
48         */
49         /*
50         如果要调用类的方法,先实例化一个类,然后分别调用
51         MathTeacher mt = new MathTeacher();
52         mt.teach();
53         mt.sleep();
54         ChineseTeacher ct = new ChineseTeacher();
55         ct.teach();
56         ct.sleep();
57         发现这样比较麻烦,向上抽取,定义一个新的工具类TeachTest,将方法封装进去
58         */
59         TeachTest tt = new TeachTest();
60         tt.teach(new MathTeacher());
61         tt.teach(new ChineseTeacher());
62     }
63 }

在多态中成员函数的特点:

在编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有,编译失败

在运行时期:参阅对象所属的类中是否有调用的方法

简单总结:成员函数在多态调用时,编译看左边,运行看右边

 

(面试)在多态中成员变量静态成员函数的特点:

无论编译或运行,都参考左边(引用型变量所属的类)

如:

1 Fu f = new Zi();
2 System.out.println(f.num);//打印的是父类里面的变量num
3 Zi z = new Zi();
4 System.out.println(z.num);//打印的是子类里面的变量num
5 //静态的方法也是一样。

 

一个集合了接口,多态的例子

 1 /*
 2 类 主板,主板有运行方法run()
 3 一段时间后想要上网 加入网卡类
 4 想要听音乐 加入 声卡类
 5 
 6 但是这样一个一个的加入使得代码的扩展性很差,每次都要重新修改很多代码
 7 
 8 于是引入一个通用的接口PCI类
 9 所有设备都有打开和关闭功能
10 让网卡和声卡分别取实现PCI接口,重写成自己的打开和关闭功能
11 
12 给主板加上一个实现pcirun的方法,传递参数的值为PCI类型的
13 可以利用多态PCI p = new NetCard();
14 
15 所以在下面主函数中运行时 创建新的主板对象以后
16         mb.pcirun(new NetCard());
17         mb.pcirun(new SoundCard());
18 就可以分别使用网卡和声卡了,如果以后还要再加入比如显卡
19 就只需要建立一个显卡类去实现PCI接口,然后直接用主板中的pcirun方法就可以了。
20 
21 */
22 class MainBoard
23 {
24     public void run()
25     {
26         System.out.println("mainboard run");
27     }
28     public void pcirun(PCI p)
29     {
30         p.open();
31         p.close();
32     }
33 }
34 interface PCI
35 {
36     public abstract void open();
37     public abstract void close();
38 }
39 class NetCard implements PCI
40 {
41     public void open()
42     {
43         System.out.println("netcard open");
44     }
45     public void close()
46     {
47         System.out.println("netcard close");
48     }
49 }
50 class SoundCard implements PCI
51 {
52     public void open()
53     {
54         System.out.println("SoundCard open");
55     }
56     public void close()
57     {
58         System.out.println("SoundCard close");
59     }
60 }
61 class Test
62 {
63     public static void main(String[] args)
64     {
65         MainBoard mb = new MainBoard();
66         mb.run();
67         mb.pcirun(new NetCard());
68         mb.pcirun(new SoundCard());
69     }
70 }
71 /*
72 这样做的好处:
73 大大的降低了主板和各种独立设备直接的耦合性
74 中间用一个PCI接口来连接起来
75 程序日后非常方便扩展
76 */
posted @ 2012-08-05 01:46  viLyo  阅读(3720)  评论(0编辑  收藏  举报