一、什么是多态
多态(Polymorphism)按字面的意bai思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。
所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,即统一性和高效性。这就是多态性。
通俗的来讲,多态就是一种事物的多种存在状态,比如白酒、红酒都属于酒,而酒又可以分为白酒红酒等。
总而言之,多态的前提是有一个父类,多个子类。
父类的对象变量可以引用本类的对象,也可以引用子类的对象。
即对象类型的转换分为以下两种:
(1) 向上转型: 子类的对象可以直接赋给父类的对象变量。
这种现象也称之为类型的自动转换。
当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作,这时就可以使用向上转型。
(2) 向下转型: 将父类的引用强制转换成子类的引用。
当要使用子类特有功能时,就需要使用向下转型。
向下转型的好处:可以使用子类特有功能。
但是弊端是需要面对具体的子类对象;在向下转型时容易发生 ClassCastException 类型转换异常。在转换之前必须做 类型判断
如: if( !a instanceof Dog){…}
注意: 它必须强制转换。
指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。
二、Java中的多态
Java的多态是java要实现的多种形式
Java实现多态有三个必要条件:
1、继承(继承是多态的基础,没有继承就没有多态):
在多态中必须存在有继承关系的子类和父类。
2、重写:(多态下会调用子类重写后的方法):
子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
3、父类引用指向子类对象(涉及子类到父类的类型转换):
在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
向上转型(Student person = new Student()):
将一个父类的引用指向一个子类对象,成为向上转型,自动进行类型转换,此时通过父类引用变量调用的方法是
子类覆盖或继承父类的方法,而不是父类的方法此时通过父类引用变量无法调用子类特有的方法。
向下转型(Student stu = (Student)person):
将一个指向子类对象的引用赋给一个子类的引用,成为向下转型,此时必须进行强制类型转换。向下转型必须
转换为父类引用指向的真实子类类型,,否则将出现ClassCastException,不是任意的强制转换
对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
例如:
public class parents {
public void baijiu(){
System.out.println("parents 的baijiu.....");
fun2();
}
public void hongjiu(){
System.out.println("parents 的hongjiu...");
}
}
public class child extends parents{
public void baijiu(String a){
System.out.println("child 的 baijiu...");
hongjiu();
}
public void hongjiu(){
System.out.println("child 的hongjiu...");
}
}
public class Test {
public static void main(String[] args) {
parents a = new child();
a.baijiu();
}
}
输出如下
parents 的baijiu.....
child 的hongjiu...
从中我们可以发现:指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。
运用多态时、需要主义注意以下几点:
1、当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。
2、要想调用父类中被重写的方法,则必须使用关键字 super。
3、同一个父类的方法会被不同的子类重写。在调用方法时,调用的为各个 子类覆盖后的方法
4、当变量名指向不同的子类对象时,由于每个子类覆盖父类方法的内容不同,所以会调用不同的方法。
三、多态的优点
使用多态,我们可以很好的完成代码的解耦和工作,加强代码的可扩展性,是代码更加灵活,在不改变原有接口方法的情况下简化流程等,总结来说即以下几点:
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
四、多态的实现方式与定义
实现方式:
方式一、重写
方式二、接口
java中的接口是一些方法特征的集合,但没有方法的实现。
方式三、抽象类和抽象方法
多态的定义格式:
普通类多态定义的格式:父类 变量名 = new 子类();
抽象类多态定义格式:抽象类 变量名 = new 抽象类子类();
接口多态定义的格式:接口 变量名 = new 接口实现类();