1.多态
1. 概述
多态:某一类事物的多种存在形态
因为有的继承,所以有了父类和子类关系,那么就提现出来了多态的特性。
当一类事物之间肯定有存在某种关系,例如儿子和父亲,学生和人,工人和人,那么他们也有共性,那么当我们划分的越细,那么子类就越多,那么我们调用相同特性的时候,就会比较麻烦,那么我们就使用父类来接受子类的对象,这样就可以调用相同的特性方法。
例如:
动物:狗,猪,兔子…等,他们都有吃的行为。
[java] view plaincopy
1. interface Animal {
2. void eat();
3. }
4. public class Dog implements Animal {
5. /*重写父类的方法*/
6. public void eat() {
7. System.out.println("狗吃骨头");
8. }
9. }
10. public class Pink implements Animal {
11.
12. /* 重写父类的方法 */
13. public void eat() {
14. System.out.println("猪吃猪饲料");
15. }
16.
17. }
18. public class DuoTaiDemo {
19. public static void main(String[] agrs) {
20. animalEat(new Dog());
21. animalEat(new Pink());
22. }
23.
24. /**
25. * 用父类来接受子类,那么就可以调用子类和父类相同的方法
26. */
27. public static void animalEat(Animal animal) {
28. animal.eat();
29. }
30. }
31. 结果:
32. 狗吃骨头
33. 猪吃猪饲料
34.
从结果可以看出,父类可以接受子类对象,相当于 Animal animal=new Dog();
结论:父类的引用指向了自己的子类对象。
父类的引用也可以接受自己的子类对象。
2. 多态的特点
要想使用多态,那么前提是:类与类之间必须有关系,存在覆盖。
多态的好处:提高了程序的扩展性,也可以减少代码。
多态的弊端:只能使用父类的引用访问子类和父类共有的方法。
3. 多态的应用
使用:可以使用父类对象作为参数接受子类对象。
向上转型:子类类型转换成父类类型。
向下转型:强制把父类的引用转换成子类类型。
Instanceof:判断是否是此类型 子类是有限的,或者是对某一特殊类型进行转换。
也可以重写基类的方法,然后把共有的方法封装到一个新的类中,这样使用就更方便了。
[java] view plaincopy
1. interface Animal {
2. void eat();
3. }
4. public class Dog implements Animal {
5. /* 重写父类的方法 */
6. public void eat() {
7. System.out.println("狗吃骨头");
8. }
9.
10. /* 自独有的方法 */
11. public void seeDoor() {
12. System.out.println("看门");
13. }
14.
15. }
16. public class Pink implements Animal {
17.
18. /* 重写父类的方法 */
19. public void eat() {
20. System.out.println("猪吃猪饲料");
21. }
22. /* 自独有的方法 */
23. public void DongDi() {
24. System.out.println("猪,gongdi");
25. }
26.
27. }
28. public class DuoTaiDemo {
29. public static void main(String[] agrs) {
30. animalEat(new Dog());
31. animalEat(new Pink());
32. }
33.
34. /**
35. * 用父类来接受子类,那么就可以调用子类和父类相同的方法
36. */
37. public static void animalEat(Animal animal) {
38. animal.eat();
39. /*instanceof 是判断是否是此类对象,十寸与此类存在某种关系
40. * 一般情况下,只有在子类比较少的情况下,才使用此比较的方式,
41. * 父类不能调用子类自己独有的方法,必须强制转换成子类对象*/
42. if(animal instanceof Dog){
43. Dog dog=(Dog)animal;
44. dog.seeDoor();
45. }else if(animal instanceof Pink){
46. Pink p=(Pink)animal;
47. p.DongDi();
48. }
49. }
50. }
51. 结果;
52. 狗吃骨头
53. 看门
54. 猪吃猪饲料
55. 猪,gongdi
4. 覆盖问题
多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法,。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
当父类和子类相同的成员变量,或者有相同的静态方法,那么父类接受子类对象的时候,那么调用相同的成员变量或者是相同的静态方法,那么就执行父类的, 因为,当父类和子类一加载的时候,那么其都在内存中生成,所以当然会调用弗雷德。
如果不是静态的方法那么会调用子类重写的方法。
[java] view plaincopy
1. public class Fu {
2. public int num=5;
3. /*静态成员*/
4. public static void show(){
5. System.out.println("父类的静态的show()方法");
6. }
7. public void print(){
8. System.out.println("父类的非静态的print()方法");
9. }
10. }
11. public class Zi extends Fu {
12. public int num=10;
13.
14. public static void show(){
15. System.out.println("子类的静态的show()方法");
16. }
17. public void print(){
18. System.out.println("子类的非静态的print()方法");
19. }
20. public static void main(String[] agrs) {
21. Fu fz = new Zi();
22. fz.show();//父类的,因为是静态的方法
23. System.out.println(fz.num);//父类的,因为是常量
24. fz.print();//子类的,因为不是静态的
25. }
26. }
27. 结果:
28. 父类的静态的show()方法
29. 5
30. 子类的非静态的print()方法
2. 示例
模拟电脑的主板和PCI功能。主板中封装了PCI,其他的网卡,声卡都实现PCI接口,不管是以后扩展什么,那么继承PCI就可以在主板上上运行。
[java] view plaincopy
1. /*PCI接口*/
2. interface PCI {
3. void open();
4. void close();
5. }
6. /*主板*/
7. class MainCard {
8. public void run() {
9. System.out.println("main cardrun");
10. }
11.
12. public void userPCI(PCI pci) {
13. if (pci != null) {// 加入PCI上不为空,
14. pci.open();
15. pci.close();
16. }
17. }
18. }
19.
20. /* 网卡 */
21. class NetCard implements PCI {
22.
23. @Override
24. public void close() {
25. System.out.println("NetCard open");
26. }
27.
28. @Override
29. public void open() {
30. System.out.println("NetCardclose");
31. }
32.
33. }
34.
35. /* 声卡 */
36. class SoundCard implements PCI {
37.
38. @Override
39. public void close() {
40. System.out.println("SoundCardopen");
41. }
42.
43. @Override
44. public void open() {
45. System.out.println("SoundCardclose");
46. }
47.
48. }
49.
50. public class TextDemo {
51. public static void main(String[] args) {
52. MainCard card = new MainCard();
53. card.run();
54. card.userPCI(new NetCard());
55. card.userPCI(new SoundCard());
56. }
57.
58. }
59. 结果:
60. main card run
61. NetCard close
62. NetCard open
63. SoundCard close
64. SoundCard open
65.