2014-10-22 145 views
0

我會盡量把這個問題作爲通用的(沒有雙關語意思)。作爲抽象方法的參數的泛型類型?

比方說,我有一個對象「車庫」,作爲汽車的容器。它看起來是這樣的:

public abstract class Garage { 
    public abstract List<? extends Car> getCars(); 
    public abstract void addCarToGarage(Car car); 
} 

因爲我很有錢,我都會有不同類型的車庫,有的只包含了我的跑車,另一隻我的越野車等。

所以我車庫的人會是這樣的:

public class SportCarGarage extends Garage { 
    @Override 
    public List<SportCar> getCars() { 
     // code to return the cards 
    } 

    @Override 
    public void addCarToGarage(Car car){ 
     // code to add car to garage 
    } 
} 

現在你可能已經看到了我的問題。我可以實現getCars(),以便它將返回SportCar的列表。但如果我打電話給addCarToGarage,我需要檢查每輛車的類型,如果有人試圖在SportCarGarage中添加SUV,我不會收到語法錯誤。

我想是這樣的:

public abstract class Garage { 
    public abstract List<? extends Car> getCars(); 
    public abstract void addCarToGarage(? extends Car car); 
} 

但是,這只是給我一個語法錯誤。我想有一個簡單的解決方案,我只是不知道要搜索什麼。希望你能幫助。

+1

不留神張貼了這個作爲一個答案前面 - 看起來像其他人已經回答了這個問題,但無論如何:有沒有什麼增加了汽車的一些根本的區別到車庫'的確,基於什麼特定類型的汽車呢?如果沒有,那麼我建議你只需在抽象類本身中實現'addCarToGarage'方法。 – Beardy 2014-10-22 12:25:09

+0

+1 for @TomFromThePool。這是泛型代碼的好處之一:爲了獲得類型安全性,不需要子類。如果車庫管理代碼可以是通用的,則不需要複製它。你只需要,如果子類有一些額外的方法,或需要根據車型做一些特別的事情。所以你可以使用'Garage '而不是'SportsCarGarage'。 – Thilo 2014-10-22 12:28:03

+0

@TomFromThePool - 我必須考慮這一點。其實TypeSafety是我目前主要關心的問題。但是Thilo提到我也可以通過其他方式獲得TypeSafety。我將不得不嘗試一下,當然,我正在進行的項目有點複雜。但謝謝你的想法。 – Feroc 2014-10-22 12:35:25

回答

3

可以使Garage通用和重複使用型的addCarToGarage方法:

public abstract class Garage<T extends Car> { 
    public abstract List<T> getCars(); 
    public abstract void addCarToGarage(T car); 
} 

然後,SportCarGarage應該是這樣的:

public class SportCarGarage extends Garage<SportCar> { 
    @Override 
    public List<SportCar> getCars() { 
     // code to return the cards 
    } 

    @Override 
    public void addCarToGarage(SportCar car){ 
     // code to add car to garage 
    } 
} 
+1

+1。除非SportsCarGarage做了非常特別的事情,否則現在看來這兩種方法不需要是抽象的(並且可以在Garage中實現)。 – Thilo 2014-10-22 12:22:26

+0

沒錯,是的。 – 2014-10-22 12:23:07

0

您需要參數化整個班級。

public abstract class Garage<T extends Car> { 
    public abstract List<T> getCars(); 
    public abstract void addCarToGarage(T car); 
} 

這也將確保您在所有方法之間使用連貫類型。

編輯:錯字

+1

你編譯過嗎? :) – 2014-10-22 12:18:48

+0

Ooops。馬虎我。 – 2014-10-22 12:20:08

0

難道你基本上只是想要以下?

public abstract class Garage<T extends Car> { 
    public abstract List<T> getCars(); 
    public abstract void addCarToGarage(T car); 
} 

而且

public class SportCarGarage extends Garage<SportCar> { 
    @Override 
    public List<SportCar> getCars() { 
     // code to return the cards 
    } 

    @Override 
    public void addCarToGarage(SportCar car){ 
     // code to add car to garage 
    } 
} 
+0

看看下面的內容:http://stackoverflow.com/a/24575113/2413303 – EpicPandaForce 2014-10-22 12:22:18

0

當然,你只需要做出車庫通用:

public abstract class Garage<T extends Car> { 
    public abstract List<T> getCars(); 
    public abstract void addCarToGarage(T car); 
} 

然後,你可以做

Garage<SportsCar> sportsGarage = .... 

我已經離開了抽象類,但也許你不需要創建子類anym礦石只是爲了適應不同類型的汽車。

現在看來你至少可以用通用的方式實現這兩個方法。

如果你真的想要的專用子類中,你可以做

class SportsGarage extends Garage<SportsCar> { 
     .... 
} 

Garage<SportsCar> sportsGarage = new SportsGarage();