面向對象之多態(Java實現)
本文借鑒於csdn,博客園,b站等各大知識分享平台
之前學習了封裝與繼承,封裝就是數據的封裝性(大致理解),繼承就是一個類繼承另一個類的屬性,稱為父子類
多態
多態是面向對象的第三大特性(共三大特性)
求面積,對於不同的圖形有不同的求法。所以說,對於同一種行為,不同的事物可以體現出不同的形態。多態,描述的就是這樣的狀態。
定義:
多態是指同一行為,具有多個不同表現形式
多態的前提:
- 繼承或者實現【二選一】
- 方法的重寫【意義體現:不重寫,無意義】
- 父類引用指向子類對象【格式體現】
格式:
父類類型 變量名 = new 子類對象;
變量名.方法名();
注意:父類類型可以是子類對象繼承的父類,也可以是實現的父接口類型
代碼:
Fu f = new Zi();
f.method();
當使用多態方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,執行的是子類重寫後方法。
可能會覺得現在暫時的使用似乎沒什麼用處,那麼如何去正確的使用其這也就是接下來所要敘述的,多態的好處
實際開發的過程中,父類類型作為方法形式參數,傳遞子類對象給方法,進行方法的調用,更能體現出多態的擴展性與便利。
定義父類:
public abstract class Animal {
public abstract void eat();
}
定義子類:
class Cat extends Animal {
public void eat() {
System.out.println("吃魚");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨頭");
}
}
定義測試類:
public class Test {
public static void main(String[] args) {
// 多態形式,創建對象
Cat c = new Cat();
Dog d = new Dog();
// 調用showCatEat
showCatEat(c);
// 調用showDogEat
showDogEat(d);
/*
以上兩個方法, 均可以被showAnimalEat(Animal a)方法所替代
而執行效果一致
*/
showAnimalEat(c);
showAnimalEat(d);
}
public static void showCatEat (Cat c){
c.eat();
}
public static void showDogEat (Dog d){
d.eat();
}
public static void showAnimalEat (Animal a){
a.eat();
}
}
由上面的代碼可以看出,showanimaleat方法的animal類型,是cat和dog的父類型,用它去接收子類對象,相當於用0-100去接洽0-10這是絕對可以收下的,因為夫類型肯定是比子類型要大
當eat方法執行的時候,多態規定,執行的是子類重寫的方法,那麼效果自然與showCatEat、showDogEat方法一致,所以showAnimalEat完全可以替代以上兩方法。
不僅僅是替代,在擴展性方面,無論之後再多的子類出現,我們都不需要編寫showXxxEat方法了,直接使用showAnimalEat都可以完成。
所以,多態的好處,體現在,可以使程序編寫的更簡單,並有良好的擴展。
引用類型的轉換
多態的轉型分為向上和向下兩種
向上轉型
向上轉型:多態本身是子類類型向父類類型向上轉換的過程,這個過程是默認的。
當父類引用指向一個子類對象時,便是向上轉型。
使用格式:
父類類型 變量名 = new 子類類型();
向下轉型
向下轉型:父類類型向子類類型向下轉換的過程,這個過程是強制的。
一個已經向上轉型的子類對象,將父類引用轉為子類引用,可以使用強制類型轉換的格式,便是向下轉型。
使用格式:子類類型 變量名 = (子類類型) 父類變量名;
為什麼要轉型
當使用多態方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤。也就是說,不能調用子類擁有,而父類沒有的方法。編譯都錯誤,更別說運行了。這也是多態給我們帶來的一點”小麻煩”。所以,想要調用子類特有的方法,必須做向下轉型。
為了避免ClassCastException的發生,Java提供了 instanceof 關鍵字,給引用變量做類型的校驗,格式如下:
變量名 instanceof 數據類型
如果變量屬於該數據類型,返回true。
如果變量不屬於該數據類型,返回false。
實例:
筆記本電腦(laptop)通常具備使用USB設備的功能。在生產時,筆記本都預留了可以插入USB設備的USB接口,但具體是什麼USB設備,筆記本廠商並不關心,只要符合USB規格的設備都可以。
定義USB接口,具備最基本的開啟功能和關閉功能。鼠標和鍵盤要想能在電腦上使用,那麼鼠標和鍵盤也必須遵守USB規範,實現USB接口,否則鼠標和鍵盤的生產出來也無法使用。
分析:
進行描述筆記本類,實現筆記本使用USB鼠標、USB鍵盤
- USB接口,包含開啟功能、關閉功能
- 筆記本類,包含運行功能、關機功能、使用USB設備功能
- 鼠標類,要實現USB接口,並具備點擊的方法
- 鍵盤類,要實現USB接口,具備敲擊的方法
實現
usb接口:
package cn.qioha.test2Interface;
public interface USB {
public abstract void on();
public abstract void off();
}
computer類
package cn.qioha.test2Interface;
public class Computer {
public void switchOn(){
System.out.println("打開計算機");
}
public void switchOff(){
System.out.println("關閉計算機");
}
public void useDevice(USB usb){
usb.on();
if(usb instanceof Mouse){
((Mouse) usb) .click();
}
else if (usb instanceof Keyboard){
((Keyboard) usb).input();
}
usb.off();
}
public static void main(String[] args) {
Computer c = new Computer();
c.switchOn();
c.useDevice(new Mouse());
c.useDevice(new Keyboard());
c.switchOff();
}
}
keyboard類:
package cn.qioha.test2Interface;
public class Keyboard implements USB{
@Override
public void on() {
System.out.println("開啟鍵盤");
}
@Override
public void off() {
System.out.println("關閉鍵盤");
}
public void input(){
System.out.println("鍵盤輸入");
}
}
Mouse類:
package cn.qioha.test2Interface;
public class Mouse implements USB{
@Override
public void on() {
System.out.println("開啟鼠標");
}
@Override
public void off() {
System.out.println("關閉鼠標");
}
public void click(){
System.out.println("鼠標點擊");
}
}
ok,大致就實現了,這裡還有很多的不足,接下來的更新我打算就更新問題即可,不再以回顧式樣的去更新博客了,對自己的問題進行一個記錄反而是更好的
多有參考,僅供學習使用,麻煩見諒,侵權我立刪!