引言:
本来想在继承那一博文中把多态写完的,但随着继承篇幅的增大,再加上多态这个让人看上去很厌烦、很复杂的问题,会是整个篇幅变得可读性极差,故灵气此文。
多态,作为面向对象三大特性之一,想必是让大家都很发疯的一项技术,作为学生,考试这里面基本上考倒一大部分人,子类父类的关系搞不清,结果更是出乎所料。本文详细阐述多态,望给大家提供些许启蒙。
多态:可以理解为事物存在的多种体现形态
1、多态的基本体现
父类的引用指向了自己的子类对象
父类的引用也可以接受自己的子类对象
2、多态的前提
必须是类与类之间有关系,要么继承,要么实现
通常还有一个前提,存在覆盖
3、多态的好处
多态的出现大大提高了程序的扩展性
4、多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类的成员
5、多态的应用
6、多态的出现代码中的特点(多态使用的注意对象)
空谈多态,太过抽象,简单说说执行结果,也不好理解,下面通过测试代码中的例子说明问题。
/* 动物 猫、狗 */ abstract class Animal { abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println("chiyu"); } public void catchMouse() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("啃骨头"); } public void kanJia() { System.out.println("看家"); } } class DuoTaiDemo { public static void main(String[] args) { Animal a=new Cat(); //类型提升。向上转型。 a.eat(); //如果想要调用猫的特有方法时,如何操作? //强制将父类的引用,转成子类类型. 向下转型 Cat c=(Cat) a; c.catchMouse(); /* 但这种绝对不行 即将父类对象转成子类类型 我们能转的是父类的引用指向子类的对象时,该应用可以被提升,也可以被强制转换。 多态自始至终都是子类对象在变化 Animal a=new Animal(); Cat c=(Cat)a; c.catchMouse(); */ } public static void function(Animal a) { a.eat(); if(a instanceof Cat) { Cat c =(Cat)a; c.catchMouse(); } else if(a instanceof Dog) { Dog c =(Dog)a; c.kanJia(); } } }
在多态中成员函数特点:
在编译时期引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败
在运行时期,参阅对象所属的类中是否有调用方法
简单总结就是成员函数在多态调用时,编译看左边,运行看右边
在多态中,成员变量的=特点:
无论是编译和运行,都是参考左边,(引用型变量所属的类)
在多态中,静态成员函数的特点:
无论编译还是运行都参考左边
abstract class Student { public abstract void study(); public void sleep() { System.out.println("躺着睡"); } } class BassStudent extends Student { public void study() { System.out.println("base study"); } public void sleep() { System.out.println("坐着睡"); } } class advStudent extends Student { public void study() { System.out.println("adv study"); } } class DoStudent { public void doSth(Student stu) { stu.study(); stu.sleep(); } } class DuoTaiDemo { public static void main(String[] args) { DoStudent ds=new DoStudent(); ds.doSth(new BaseStudent()); ds.doSth(new advStudent()); /* BaseStudent bs=new BaseStudent(); bs.study(); bs.sleep(); */ } }
需求:
电脑运行实例:
电脑运行基于主板
interface PCI { public void open(); public void close(); } class MainBoard { public void run() { System.out.println("mainboard run"); } public void usePCI(PCI p)//接口型引用指向子类创建的对象 { if(p!=null) { p.open(); p.close(); } } } class NetCard implements PCI { public void open() { System.out.println("netcard open "); } public void close() { System.out.println("netcard close"); } } /* class MainBoard { public void run() { System.out.println("mainboard run"); } public void useNetCard(NetCard c) { c.open(); c.close(); } } class NetCard { public void open() { System.out.println("netcard open "); } public void close() { System.out.println("netcard close"); } } */ class DuoTaiDemo5 { public static void main(String[] args) {/* MainBoard mb=new MainBoard(); mb.run(); mb.useNetCard(new Netcard()); */ MainBoard mb=new MainBoard(); mb.run(); mb.usePCI(null); mb.usePCI(Netcard()); } }