关系有一个继承和铸造

时间:2017-07-19 09:33:25

标签: java oop inheritance

假设我有以下类:

abstract class AbstractEngine{...}
abstract class AbstractTransmission {...}
abstract class AbstractCar {
   private AbstractEngine engine;
   private AbstractTransmission transmission;
   //setters and getters 
  ...
}

class ConcreteEngine extends AbstractEngine{...}
class ConcreteTransmission extends AbstractTransmission{...}
class ConcreteCar extends AbstractCar {
   public void move() {
      ConcreteEngine engine = (ConcreteEngine)getEngine();
      ConcreteTransmission transmission = (ConcreteTransmission) getTransmission();
      ....
   }
}

正如您在ConcreteCar中看到的那样,我们将使用大量的铸件来处理具体细节。在我看来,我在这里做错了什么。无论如何,我可以使用has a关系和继承避免这么多的投射吗?

3 个答案:

答案 0 :(得分:1)

你是对的,这种向下倾斜通常是设计糟糕的症状。

在你的情况下 - 你的抽象似乎不够好。

换句话说:您的 base (抽象)类应该提供处理相应对象所需的所有*行为。

含义:对于AbstractEngine的用户来说,绝对这个对象后面的实现是什么。因此:查看您的抽象类提供的接口;并以一种允许你在没有实例检查和向下转换的情况下执行必要事物的方式进行返工。

将您的功能“拆分”为一组接口也可能是值得的;允许您进行更多“细粒度”的功能切片。

答案 1 :(得分:1)

我认为这是使用泛型的典型示例。如果您修改代码,则不需要类型转换:

abstract class AbstractEngine{};
abstract class AbstractTransmission {};
abstract class  AbstractCar<E extends AbstractEngine, T extends AbstractTransmission> {
    private E engine;
    private T transmission;
    public E getEngine() {
        return engine;
    }
    public T getTransmission() {
        return transmission;
    }
}

class ConcreteEngine extends AbstractEngine{};
class ConcreteTransmission extends AbstractTransmission{};
class ConcreteCar extends AbstractCar<ConcreteEngine, ConcreteTransmission> {
   public void move() {
      ConcreteEngine engine = getEngine();
      ConcreteTransmission transmission = getTransmission();
   }
}

答案 2 :(得分:-1)

你应该利用多态性。尝试

AbstractEngine engine = getEngine()

这将编译,因为ConcreteEngine是一个AbstractEngine。这也是更好的OOP实践,因为这样你的程序将更灵活地适应未来的变化。