目錄
- 概念
- 多型呼叫成員的特點
- 多型的優勢和弊端
概念
多種形態,完成某個行為,當不同的物件去完成時會產生出不同的狀態,簡而言之,同型別的物件,表現出不同狀態及物件的多種形態
其好處是使用父類作為引數,可以接收所有子類物件,體現了多型的擴充套件性與便利。
程式碼如下(示例):
父類型別 物件名稱 = 子類物件例項;
Fu f = new Zi();
前提:
-
1.存在繼承關係
-
2.有父類引用指向子類物件
-
3.子類必須要對父類中方法進行重寫
-
4.透過父類的引用呼叫重寫的方法
舉例
在這裡插入程式碼片class Teacher extends Person{
@Override
public void show(){
System.out.println("名字為"+this.getName()+"正在教學生讀書");
}
}
class Student extends Person{
@Override
public void show(){
System.out.println("名字為"+this.getName()+"正在讀書");
}
}
class Person {
private String name;
private int age;
//無參構造
public Person(){};
public Person(String name,int age){
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println(this.name + "正在玩");
}
}
public class Test {
public static void main(String[] args) {
Student s= new Student();
s.setName("小鄔");
s.setAge(30);
Teacher t = new Teacher();
t.setAge(25);
t.setName("王老師");
register(t);
register(s);
}
//用來接收類
public static void register(Person p){
p.show();
}
}
多型呼叫成員的特點
變數呼叫:編譯看左邊,執行也看左。
方法呼叫:編譯看左邊,執行看右邊。
以下程式碼實現:
``public class Test1 {
public static void main(String[] args) {
//建立物件
Animal a = new Dog();
//呼叫成員變數:編譯看左邊,執行也看左邊
//編譯看左邊:javac編譯程式碼的時候,會看左邊的父類中有沒有這個變數,如果有,編譯成功,如果沒有,編譯失敗
//執行看左邊:javac編譯程式碼的時候,實際獲取的就是左邊父類成員變數的值
System.out.println(a.name);
//呼叫成員方法:編譯看左邊,執行看右邊
//編譯看左邊:javac編譯程式碼的時候,回看父類中有沒有這個方法 有則編譯成功,否則編譯失敗
//執行看右邊:實際上執行的是左邊的子類的方法
a.show();
//現在會用Animal這個類的 變數 a來呼叫
//成員變數:在子類的物件中,會把父類的成員變數也會繼承下來。父是name 子也是name
//成員方法:如果子類方法進行了重寫,那麼在虛方法表中會把父類的方法進行覆蓋的。
}
}
class Animal{
String name = "動物";
int age;
public void show(){
System.out.println("Animal~~~~~~~~show");
}
}
class Dog extends Animal{
String name = "狗";
@Override
public void show(){
System.out.println("Dog~~~~~~~~show");
}
}
多型的優勢和弊端
優勢
1.在多型形式下,右邊物件可以實現解耦合,便於擴充套件和維護
-
Person p =new Student();
-
p.work();//業務發生改變時,後續程式碼不用修改
2.定義方法的時候,使用父類作為引數,可以接收所有子類物件,體現多型的擴充套件性與便利。
弊端
1.不能呼叫子類的特有功能
原因:javac 在編譯的時候會第一時間在父類中檢查是否存在這個功能,沒有就會報錯。
那該怎麼解決呢?
變會子類型別就可以了
Animal a = new Dog();
Dog d = (Dog) a;
然後再呼叫子類的方法就可以了**,但是注意轉換的時候不能瞎轉,如果轉成其他型別就會報錯。
所有上面程式碼可以寫成這種
Animal a = new Dog();
if(a instanceof Dog){
Dog d = (Dog) a;
}
//其次
還可以寫成
Animal a = new Dog();
if(a instanceof Dog d)
//這裡先判斷a是不是Dog型別,是,則強轉為Dog型別,並把變數名改為d
//如果不是,則不能強轉並且結果是false
這是的instanceof 是一個關鍵字 判斷的是 a 這個變數所指向的物件是不是 Dog 型別 ,否則不能強轉;
總結
- 1.多型的優勢:方法中,作為父型別作為引數,可以接收所有子類物件
- 2.多型的弊端:不能使用子類的特有功能
- 3.引用資料型別的型別轉換:自動型別轉換、強制型別轉換(可以轉換真正的子類型別,呼叫子類的獨有功能)