Java继承; 将子类传递给超类的抽象方法

3

抱歉标题不够清晰。以下是我的结构:

public interface Vehicle {...}
public class Car implements Vehicle {...}

那么:

public abstract class Fixer {
...
   abstract void fix(Vehicle vehicle);
...
}

我希望你能为我提供以下服务:

public class CarFixer extends Fixer {
    void fix(Car car) {...}
}

但是这个不起作用。Eclipse表示:The type CarFixer must implement the inherited abstract method Fixer.fix(Vehicle)。你有什么办法可以解决这个问题吗?

1
这是因为Eclipse是正确的。重载不等于覆盖。考虑一个通用的“Fixer”类,也许? - awksp
2个回答

9
你可以使用泛型来解决这个问题:
public abstract class Fixer<T extends Vehicle> {
    abstract void fix(T vehicle);
}

public class CarFixer extends Fixer<Car> {
    void fix(Car car) {...}
}

您原始版本的问题在于fix方法允许任何类型的车辆,但是您的实现类只允许汽车。请考虑以下代码:
Fixer fixer = new CarFixer();
fixer.fix(new Bike()); // <-- boom, `ClassCastException`, Bike is a vehicle but not a car

3
你已经了解了Java中的泛型。泛型提供了一种类似“通配符”的类型,其中一个类或方法可以指定“我们不关心它是什么类型,我们只需要一个类型”。
泛型允许超类子类中强制执行特定类型,而不是允许任何扩展某个类的类。这意味着你最终将强制执行新的最高允许超类作为参数(即Vehicle不再是您可以传递给fix()的最基本可允许类型;现在是任何子类说它是什么,只要那个任意类型扩展Vehicle)。
泛型常见于容器类(例如ListMapSet),其中容器并不真正关心它跟踪的是什么类型,而是专注于实际跟踪和管理这些实例。
泛型由一个或多个类型占位符组成(在Java中,ET通常用于占位符,但名称并不重要;它们通常遵循正常的类型命名约定),用于代替特定类或超类。
在您的代码中,您希望子类根据其确切相关类型实现方法(即CarFixer将接受CarJetpackFixer将接受Jetpack),但您希望强制执行这些类型扩展Vehicle。为了强制执行这一点,您必须告诉Fixer类您的子类想要什么。
public abstract class Fixer <E extends Vehicle>
{
    abstract void fix(E vehicle);
}

你的子类然后扩展Fixer,将E填入它想要的类型。

public class CarFixer extends Fixer<Car>
{
    @Override
    void fix(Car vehicle)
    {
         // ...
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接