java泛型學習和實踐(2)

引言

上節中簡單介紹了泛型基本使用方法及使用泛型帶來的安全性和可讀性好處,接下來繼續思考第二版代碼的不足之處。回顧第二版Driver類的drive方法,其接收T泛型參數,爲了調用具體car的run方法,需要向下轉型,進行了多次instanceof判斷,代碼冗餘且擴展性不好,不符合代碼設計的"開閉原則"。有沒有更好的方式?

根據“依賴反轉”原則,即代碼應當依賴於抽象,而不是具體。由於T類型可以是任意具體的類型,所以在方法體中只能當作一般的Object進行處理,那如果可以限制T的具體類型呢,讓T類型必須是某個類的子類或實現某個接口呢,那麼問題就解決了。請看改進後的代碼

第三版

第三版代碼如下:

public interface Runnable {
    public void run();
}
public class Buick implements Runnable {
    
    @Override
    public void run(){
        System.out.println("buick run");
    }
    
    public void autoRun(){
        System.out.println("buick auto-run");
    }
}
public class Ford implements Runnable  {
    
    @Override
    public void run(){
        System.out.println("ford run");
    }
    
    public void fly(){
        System.out.println("ford fly");
    }
}
public class Driver<T extends Runnable> {
    
    private T car;
    
    public void drive(T car){
        this.car = car;
        System.out.println("I am driving a " + car);
        car.run();
    }
    
    public T getDrivingCar(){
        return car;
    }
    
    public static void main(String[] args) {
        Driver<Ford> driver1 = new Driver<Ford>();
        driver1.drive(new Ford());
        Driver<Buick> driver2 = new Driver<Buick>();
        driver2.drive(new Buick());
        
        //...執行其它業務邏輯
        
        /** 獲取司機1開的福特車執行fly方法 */
        driver1.getDrivingCar().fly();
        
        /** 獲取司機2開的別克車執行autoRun方法 */
        driver2.getDrivingCar().autoRun();
        
    }
}

跟前一版本相比,增加了Runnable接口(不要跟多線程的Runnable接口混洧,如有雷同,純屬巧合),Ford和Buick都實現了該接口。最主要的修改在Driver類的泛型T聲明上,將<T>改爲<T extends Runnable>,這樣改的意思是指,T泛型代表任意實現或繼承Runnable接口的具體類型,這樣就能夠在方法體中直接調用Runnable接口中的run方法。

這樣改的另一個好處是,由於drive方法接收的參數是基於接口的,這樣即使傳入參數是另外的車類型(比如奔馳車),代碼也不需要進行任何修改,完全符合代碼設計中“對擴展開放,對修改關閉”的原則。

泛型聲明<T extends Runnable>意味着T類型必須是Runnable接口的子接口或實現類。更一般化的,可以是<T extends Parent>,Parent可以是接口,抽象類或一般類。T具體類型必須是Parent的子類或實現類或Parent自身。

上面介紹了extends關鍵字在泛型聲明中的使用。下面介紹下如何在方法上進行泛型聲明並使用。今天就寫到這了,明天繼續

發佈了59 篇原創文章 · 獲贊 62 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章