2014-10-22 125 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();