# 多態
從某種意義上來說,封裝和繼承都是為了多態而準備的。
在Java中多態性可以分為兩種不同的展現形式。
## 方法的多態性(編譯時多態)
前面我們在兩處地方提到了方法的多態性,一是方法的重載,還有是方法的重寫。
> 方法重載多態性的意義在于一個方法名稱有不同的實現;
> 方法重寫多態性的實現在于,父類的一個方法,不同的子類可以有不同的實現
## 對象的多態性(運行時多態)
我們在Java程序中說的多態大多指的是運行時多態,所以我們后面直接用多態稱呼。
> Java引用類型變量有兩種類型:一種是編譯時的類型,一種是運行時的類型。
* 編譯的類型是由聲明變量的時候決定的。
* 運行時類型由實際賦給該變量的對象決定。
```
//比如聲明變量類型為Animal,實際賦給該變量的對象類型為Dog
Animal animal = new Dog();
```
**如果運行時的類型和編譯時的類型不一致就會出現所謂的多態**。
* 首先編譯時類型和運行時類型是一種父類和子類的關系。
* 多態最常用的場景就是子類重寫父類的方法后,如果引用變量的類型為父類,而對象為子類,如果引用類型調用重寫方法,會去執行子類定義的實現。
```java
//父類
public class Animal {
public void say(){
System.out.println("我是一個動物");
}
}
//子類1
public class Cat extends Animal{
public void say(){
System.out.println("我是一個貓");
}
}
//子類2
public class Dog extends Animal{
public void say(){
System.out.println("我是一個狗");
}
}
//測試類
public class Test {
public static void main(String[] args) {
//簡單的子類繼承 以及實例化對象
/**Dog dog=new Dog();
dog.say();
Cat cat=new Cat();
cat.say();**/
//多態測試
// 父類引用指向Dog子類的具體實現
Animal animal=new Dog();
animal.say();
// 更換實現
animal=new Cat();
animal.say();
}
}
```
## 引用類型的強制類型轉換
```
//對象的轉型
//對象向上轉型:子類對象->父類對象 安全
//最大特點在于可以通過父類對象自動接收子類實例
Animal animal=new Dog();
//對象向下轉型(引用類型的強制類型轉換):父類對象->子類對象 不安全
// 向下轉型
//必須向發生向上轉型,才可以進行向下轉型。
Dog dog=(Dog) animal;
dog.say();
// 向下轉型 因為animal指向的是Dog具體實現 所以會報錯
Cat cat=(Cat)animal;
cat.say();
```
編寫Java程序時,引用變量只能調用他編譯時的方法,而不能調用其運行時類型的方法。如果你必須要調用其運行時的類型,則需要進行強制類型轉換。
強制類型轉換是把大的類型轉換為小的類型。
在我們的引用數據里,大的類型是父類,小的類型是子類。
只可能發生在子類和父類的關系中
## instanceof運算符
instance運算符的前一個操作數一般是引用數據類型變量,后一個操作數是類名(接口),它是用于判斷前面的對象是否是后面的類、或者其子類。如果是的話,返回true。
> instanceof運算符一般用于在我們對引用數據類型進行強制類型轉換之前判斷使用。
> 避免在實際的運行過程中出現 ClassCastException
實例代碼:
~~~
public class Client1 {
public static void main(String[] args) {
Animal tom = new Dog();
Animal mimi = new Cat();
Animal ani1 = new Animal();
if (ani1 instanceof Dog) { // 此處ani1的數據類型為 Animal 所以運算的結果為 false
Dog dog1 = (Dog) ani1;
System.out.println(dog1.getAge());
}
if (tom instanceof Dog) { // 此處tom運行時數據類型為 Dog 所以運算的結果為 true,可以進行轉換
Dog dog2 = (Dog) tom; // 強制類型轉換
dog2.setAge(20);
System.out.println(dog2.getAge());
}
tom.cry();
mimi.cry();
}
}
~~~
- JAVA基礎
- JAVA開發準備
- JAVA介紹
- 開發JAVA的準備
- JAVA的運行原理
- JDK配置
- 我的第一個JAVA程序
- 類與對象
- 基礎語言要素
- 數據類型
- eclipse的安裝與使用
- 變量
- 直接量
- 運算符
- 流程控制
- 數組結構
- 面向對象
- 隱藏與封裝
- 深入構造器
- 類的繼承
- 多態
- 包裝類
- final修飾符
- 抽象類
- 接口
- 內部類
- 設計模式
- 單例模式
- 工廠模式
- 集合框架
- 集合排序
- 常用類學習
- 異常處理
- Java基礎測試
- 綜合案例一
- JAVA高級
- 泛型
- 多線程
- 線程的創建
- 線程的生命周期
- 線程同步
- 線程通信
- 輸入輸出流(I/O編程)
- File文件操作
- 字節流與字符流
- 數據庫
- 數據庫介紹
- 數據庫安裝
- SQL
- 表的基本操作
- 修改數據語句
- 數據檢索操作
- 多表數據操作
- 表結構設計
- 綜合應用