目錄
- 滿足多態的條件
- 動態綁定第一步
- 動態綁定第二步
- 動態綁定第三步
- 參數列表,返回類型,訪問修飾限定符區別
- 有動態綁定,那是不是有靜態綁定
- 向下轉型
- 抽象類
- 接口
- 實現多個接口(先繼承再接口,接口用",")
滿足多態的條件
定義:去完成某個狀態的時候,當不同的對象去完成的時候會產生不同狀態(通俗理解為看人下菜)
滿足多態的條件:
1>必須在繼承關系上,才可以向上轉型
2>子類和父類有同名的覆蓋(重寫)方法
3>通過父類對象的引用,去調用這個重寫的方法
完成以上的三個部分,就會發生動態綁定,動態綁定為多態的基礎
通過父類的引用,只能調用父類自己獨有的屬性,方法,構造方法
動態綁定第一步
向上轉型:子類定義的變量,方法給父類
Dog dog = new Dog("小黃",8);
Animal animal = dog;
Animal animal = new Dog("小黃", 8);
這個被稱為直接賦值型
是通過animal這個引用指向了dog這個引用所指向的對象
傳參時候進行向上轉型(方法的參數)
public static void func1(Animal animal){}
public static void main(String [ ] args){Dog dog = new Dog("小黃",8);func1(dog);
}
返回值進行向上轉型
public static Animal func2( ){Dog dog = new Dog("小黃", 8);return dog;
}
動態綁定第二步
public static Animal func2( ){System.out.println(this.name + "吃飯");
}
@Override(可以在此寫注釋,起到防止錯誤作用)
public void eat( ){System.out.println(this.name + "吃狗糧");
}
注意:
1>在這里面,返回值,方法名以及參數鏈表要相同
2>被重寫的訪問修飾限定符,子類一定要大于父類
3>被private修飾的方法不可重寫
4>被static修飾的方法不可以重寫
5>被final修飾的方法不可重寫
6>構造方法不可以重寫
動態綁定第三步
Animal animal = new Dog("小黃",8);
animal eat( );
在產生了重寫以后,animal忽然就變成了調用子類的eat.這個過程就叫做動態綁定
父類與子類也可以構成重寫,被稱為協變類型
public Dog eat( ){System.out.println(this.name + "吃飯");return null;
}
public Animal eat( ){System.out.println(this.name + "吃狗糧");
}
所有的父類,默認都是Object類
public static void eatFun(Animal animal){animal.aet( );
}
public static void main(String [ ] args){Dog dog = new Dog("小黃", 8);eatFun(dog);Cat cat = new Cat("三月",6);eatFun(cat);
}
當父類的引用,引用的子類對象不一樣的時候,調用這個重寫的方法,表現出的行為是不一樣的,我們把這種思想叫做多態
參數列表,返回類型,訪問修飾限定符區別
有動態綁定,那是不是有靜態綁定
add(int a, int b)
add(int a, int b, int c)
main( ){add(1, 2);add(1, 2 ,3);
}
這上面這種就是靜態綁定
向下轉型
顧名思義,就是父類給子類
Animal animal = new Dog("小黃", 8 );
//狗可以為一個動物
Animal animal = new Cat ("三月", 6);
//貓也可以為一個動物Animal animal = new Dog("小黃", 8 );
Dog dog = animal;
//但是在這個里面,動物不一定是狗,
//所以向下轉型是不安全的Animal animal = new Dog ("小黃", 8 );
Dog dog = (Dog) animal;
//因為本身不安全的,所以這里要進行強轉
dog.bark( );Cat cat = (Cat)animal;
cat.miaomaio( );
//這里的話就會錯,因為animal在上面是引用對象為Dog,
//所以dog可以成功轉型,Cat就不可以
在父類的構造方法里面,可以調用子類和父類重寫的方法,此時會調用子類的方法,此時也會發生動態綁定,但是注意,不可以這么寫
抽象類
abstract class Shape{public abstract void draw( );
}
1>abstract修飾的類,方法為抽象類(方法)
2>抽象類不可以實例化一個對象
3>抽象類中可以和普通類一樣,定義方法和變量
4>當一個普通類繼承了抽象類,那么要重寫這個抽象類中的抽象方法
5>抽象類的出現就是為了被繼承
6>abstract 和 final 是天敵,不可以共存
7>被private static 修飾的這個抽象方法也不可以
接口
語法:
1>interface方法來修飾的(就是創建方法時候,把class換成interface)
2>接口中不可以被實現的方法,只有抽象方法(static , deafult修飾的不受限制)
3>接口中的抽象方法,默認都是public abstarct 修飾的
4>接口中的成員變量,默認都是public static final修飾的
5>接口不能進行實例化
6>類和接口之間的關系,可以使用implements來進行關聯
7>接口也有對應的字節碼文件
注意:
1>接口中的方法不可以在接口中實現,只能由實現接口的類來實現
2>接口中不能包含構造方法,以及靜態代碼塊
實現多個接口(先繼承再接口,接口用",")
interface A{void test A( );
}
interface B extends A{void test B( );
}
這個里面的話,B也具備了A的功能,但是后面用接口B的時候,B和A都要重新實現
2個關系
1>類與接口之間的關系,用implements
2>接口與接口之間的關系,用extends