1.多态的体现
父类 对象名 = new 子类();
func(父类 子类对象){}
父类的引用指向了自己的子类对象;
父类的引用可以接受自己的子类对象。
2.多态的前提
必须是类与类之间有extends/implements关系。
还有一个前提,子类对父类的成员存在覆盖
3.多态的特点
提高了程序的扩展性,但只能使用父类的引用访问父类的成员
4.多态的应用
类型提升(向上转型):子类提升为父类。父类引用指向子类对象。Animal a = new Cat();
想调用子类的方法时,需要向下转型(强制将父类的引用转成子类类型)。Cat c = (Cat)a, c.方法 实现调用
不可以将父类对象转成子类类型的引用。多态始终都是子类对象在做着变化。
但是如果向带有父类引用参数的方法中传入其他子类对象,虽然编译通过但是运行会出错(类型转换异常)。因此可以使用引用数据类型之间的判断(引用变量 instanceof 类型),从而使用特定子类类型进行指定操作
例如传入Animal a,则判断是if(a instanceof Cat)
多态中非静态成员的函数
编译时:参阅引用型变量所属的类中是否有需要调用的方法,如果有,编译通过,如果类中没有需要调用的方法则编译失败。
运行时:参阅对象所属的类中是否有需要调用的方法。
编译看左边,运行看右边
注意:多态中,成员变量的特点。无论编译和运行,变量的值都参考左边(引用变量所属类)。多态中,静态成员函数无论编译和运行都参考左边(这是因为静态比对象先加载,静态绑定,等于类名.成员,而动态的是this.)。
举例:主板、多态
实现:插入网卡时调用网卡的功能,插入声卡时调用声卡的功能,即插即用
步骤:
定义一个PCI接口,使得网卡、声卡等类implementsPCI,在调用的时候有PCI p = new 网卡();传入一个PIC型的引用变量,相当于父类引用子类对象,子类对接口的功能进行复写,从而对子类的方法进行调用。
举例:数据库提高扩展性
步骤:连接数据库,操作数据库(c r u d),关闭数据库连接
定义了接口,包含抽象方法add,delete,子类实现了接口的方法,调用时使用多态,使主程序调用重写后的子类方法,每当我们需要用到新的数据库类型时,只需要让新子类实现接口,然后作为子类调用即可
Object类:是所有对象的直接后者间接父亲,定义了所有对象都具备的功能。
所有的对象都能比较。equals()方法比较地址值,只要是Object都能比较,因此不管对象是什么类,都是Object的子类,都是多态。
通过向下转型,对equals方法进行重写,如果要用到对象的属性,需要进行类型转换和判断。如果是不同的类进行比较,则通过instanceof判断直接返回false。
toString():返回对象的字符串表示
hashCode():返回对象的哈希值
getClass()
getMethod():连private都能获取
getName()
这些都没有意义,可以在类中根据需要进行复写
内部类
内部类可以直接访问外部类的成员,包括private