Java 泛型类型作为抽象方法的参数?

Java 泛型类型作为抽象方法的参数?,java,generics,Java,Generics,我会尽可能地问这个问题,不要用双关语 假设我有一个对象“车库”,它作为汽车的容器。它看起来像这样: public abstract class Garage { public abstract List<? extends Car> getCars(); public abstract void addCarToGarage(Car car); } public class SportCarGarage extends Garage { @Override

我会尽可能地问这个问题,不要用双关语

假设我有一个对象“车库”,它作为汽车的容器。它看起来像这样:

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
    }
}
public abstract class Garage {
    public abstract List<? extends Car> getCars();
    public abstract void addCarToGarage(? extends Car 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
    }
}

但这只会给我一个语法错误。我想有一个简单的解决办法,我只是不知道该找什么。希望您能提供帮助。

您需要参数化整个类

public abstract class Garage<T extends Car>  {
    public abstract List<T> getCars();
    public abstract void addCarToGarage(T car);
}
公共抽象类车库{
公共摘要列表getCars();
公共车库(T型车);
}
这还将确保在所有方法之间使用一致的类型


编辑:输入错误

您需要参数化整个类

public abstract class Garage<T extends Car>  {
    public abstract List<T> getCars();
    public abstract void addCarToGarage(T car);
}
公共抽象类车库{
公共摘要列表getCars();
公共车库(T型车);
}
这还将确保在所有方法之间使用一致的类型


编辑:键入

您可以使
车库
通用,并在
addCarToGarage
方法中重复使用该类型:

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

您可以将
Garage
设置为通用,并在
addCarToGarage
方法中重复使用该类型:

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

你不是基本上只想要以下几点吗

public abstract class Garage<T extends Car> {
    public abstract List<T> getCars();
    public abstract void addCarToGarage(T car);
}
公共抽象类车库{
公共摘要列表getCars();
公共车库(T型车);
}

公共级SportCarGarage扩展车库{
@凌驾
公共列表getCars(){
//返回卡的代码
}
@凌驾
公共车库(跑车){
//将汽车添加到车库的代码
}
}

您基本上不是只想要以下内容吗

public abstract class Garage<T extends Car> {
    public abstract List<T> getCars();
    public abstract void addCarToGarage(T car);
}
公共抽象类车库{
公共摘要列表getCars();
公共车库(T型车);
}

公共级SportCarGarage扩展车库{
@凌驾
公共列表getCars(){
//返回卡的代码
}
@凌驾
公共车库(跑车){
//将汽车添加到车库的代码
}
}

当然,您只需将车库设置为通用:

public abstract class Garage<T extends Car> {
   public abstract List<T> getCars();
   public abstract void addCarToGarage(T car);
}
公共抽象类车库{
公共摘要列表getCars();
公共车库(T型车);
}
那你就可以了

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

Garage<SportsCar> sportsGarage = new SportsGarage();
车库运动车库=。。。。
我将类保留为抽象类,但也许您不需要再创建子类,只是为了适应不同类型的汽车

现在看来,您至少可以以通用的方式实现这两种方法

如果你真的想要专门的子类,你可以这样做

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

Garage<SportsCar> sportsGarage = new SportsGarage();
class SportsGarage扩展车库{
....
}
车库运动车库=新的运动车库();

当然,您只需将车库设置为通用:

public abstract class Garage<T extends Car> {
   public abstract List<T> getCars();
   public abstract void addCarToGarage(T car);
}
公共抽象类车库{
公共摘要列表getCars();
公共车库(T型车);
}
那你就可以了

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

Garage<SportsCar> sportsGarage = new SportsGarage();
车库运动车库=。。。。
我将类保留为抽象类,但也许您不需要再创建子类,只是为了适应不同类型的汽车

现在看来,您至少可以以通用的方式实现这两种方法

如果你真的想要专门的子类,你可以这样做

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

Garage<SportsCar> sportsGarage = new SportsGarage();
class SportsGarage扩展车库{
....
}
车库运动车库=新的运动车库();

你编译过吗?:)你编译过吗?:)+1.除非SportsCarGarage做了一些非常特殊的事情,否则这两种方法现在似乎不需要抽象(并且可以在Garage中实现)。+1。除非SportsCarGarage做了一些非常特别的事情,否则这两种方法现在似乎不需要抽象(并且可以在Garage中实现)。之前无意中将此作为一个答案发布-看起来其他人已经回答了这个问题,但无论如何:“在车库中添加一辆车”有什么根本区别吗,根据它是什么类型的车?如果没有,那么我建议您只需在抽象类本身中实现'addCarToGarage'方法。@TomFromThePool的+1。这就是泛型代码的好处之一:不需要为了类型安全而使用子类。如果车库管理代码可以是通用代码,则无需复制。如果子类有一些额外的方法或者需要根据汽车类型做一些特殊的事情,那么您只需要这样做。所以你可以用
Garage
而不是
sportscaragarage
@tom来代替这个工具-我必须考虑一下。实际上,打字安全是我目前最关心的问题。但是Thilo提到我也可以通过另一种方式获得打字安全性。我得试试,当然我正在做的项目要复杂一点。但是谢谢你的想法。之前无意中发布了这个作为答案-看起来其他人已经回答了这个问题,但不管怎样:“在车库中添加一辆车”有什么根本性的区别吗,取决于它是什么类型的车?如果没有,那么我建议您只需在抽象类本身中实现'addCarToGarage'方法。@TomFromThePool的+1。这就是泛型代码的好处之一:不需要为了类型安全而使用子类。如果车库管理代码可以是通用代码,则无需复制。如果子类有一些额外的方法或者需要根据汽车类型做一些特殊的事情,那么您只需要这样做。所以你可以用
Garage
而不是
sportscaragarage
@tom来代替这个工具-我必须考虑一下。实际上,打字安全是我目前最关心的问题。但是Thilo提到我也可以通过另一种方式获得打字安全性。我得试试,当然我正在做的项目要复杂一点。但是谢谢你的主意。