0

我有一个类(假设是 Vehicle),其中包含相当多的子类(Car、Bike、..)。每个子类都存储有关子类类型的特定信息(轮胎#,..)。

我想确保所有这些信息都已经被强制执行(在编译时)。所以我不想在子类的构造函数中指定这些数据(因为我可能会忘记设置其中的一些)。我可以将这些信息放在 Vehicle 的构造函数中,但这会使代码非常混乱,因为我有很多这些参数。

public class Vehicle {
  int numberOfTires;

  public Vehicle(int numberOfTires, ...) {
    ...
  }

}

public class Bike {
  public Bike() {
    super(2,...);
    ...
  }

}

我最终得到了完全不可读的构造函数。它还将存储每个实例的此信息,即使它特定于子类。

另一种方法是引入抽象静态 getter/setter 并将信息存储在子类中。

public class Vehicle {

  ...
  abstract public int getNumberOfTires();

}

public class Bike {

    static int numberofTires = 2;

    ...

    public int getNumberOfTires() {
      return numberOfTires;
  }

}

这看起来更干净,并且还存储每个子类而不是每个实例的信息,但是子类中会有很多代码重复。目前,所有子类都包含约 20 个 setter/getter,但几乎没有真正的功能。有没有避免这种情况的干净方法?也许使用工厂方法或类似方法?

4

3 回答 3

0

在你的鞋子里,我会这样做

public abstract class Vehicle {
    public abstract int getNumberOfTires();
}

public class Bike extends Vehicle {

    @Override
    public int getNumberOfTires() {
        return 2;
    }

}

public class Car extends Vehicle {

    @Override
    public int getNumberOfTires() {
        return 4;
    }

}
于 2014-06-19T13:36:15.340 回答
0

在我看来,你在这里谈论的是常量,例如在运行时不应该改变的值。在 Java 中,常量是具有以下限定符的变量:static final,以及private/ public。然后,您将不需要二传手,因为Bike例如,除了 2 个轮子之外,a 永远不会有任何其他东西。

我并没有真正看到有很多 getter 和 setter 的问题,你的Bike-class 有一组描述它的属性,它们都是必需的。所以像:

public abstract class Vehicle {
    public abstract int numberOfTires();
    public abstract boolean hasEngine();
}

public class Bike extends Vehicle {

    private static final int NUMBER_OF_TIRES = 2;
    private static final boolean HAS_ENGINE = false;

    public int numberOfTires() {
        return NUMBER_OF_TIRES;
    }

    public boolean hasEngine() {
        return HAS_ENGINE;
    }
}

这些变量是您所代表的实体的属性,根据面向对象的原则,它们属于类的成员。

所有域类都会有许多变量,在大多数情况下,它们至少需要一个 getter,这是没有办法的。尽管如此,保持你的领域类尽可能小是好的,不一定与代码行、它所代表的概念有关。如果域类变得很大,请将其分解,并将属于一起的变量分组为单独的类。然后每个较小的类将有一个带有有限数量变量的构造函数和实例创建

如果所有这些都对限制子类中的代码量很重要,您可以执行以下代码。我不确定我是否会推荐它,而且我认为我不会在实践中这样做。

public abstract class VehicleInfo {
    public abstract int numberOfWheels();
}

public class BikeInfo extends VehicleInfo {
    @Override
    public int numberOfWheels() {
        return 2;
    }
}

public class CarInfo extends VehicleInfo {
    @Override
    public int numberOfWheels() {
        return 4;
    }
}

public class Vehicle {
    final VehicleInfo info;
    Vehicle(final VehicleInfo info) {
        this.info = info;
    }

    public int numberOfWheels() {
        return info.numberOfWheels();
    }
}

public class Bike extends Vehicle {

    public Bike() {
        super(new BikeInfo());
    }
}

public class Car extends Vehicle {

    public Car() {
        super(new CarInfo());
    }
}

这样,所有的 getter 都位于超类(以及信息类)中,并且子类可以保持干净。

于 2014-06-19T13:37:05.787 回答
0

你应该把Vehicule所有常见的东西都放在你的课堂上。如果轮胎的数量是你所有的共同属性,Vehicule那么它就属于那里。

使用工厂模式,您可以避免每次需要类Bike中所需的所有实例时都必须编写,Vehicule因为工厂会这样做。这意味着设置 a 参数的代码Bike写在一个地方,即BikeFactory类。

这将使创建的线条Bike看起来像

Bike yourBike = BikeFactory.getInstance().create();

代替

Bike yourBike = new Bike(numberOfTires, ... );

工厂要么有一条看起来像上面的线路,要么有一堆对 setter 的调用。我建议您使用 setter 和只使用new Bike()没有参数的构造函数。

工厂、方法和作为单例的工厂的命名仅作为示例,可以按照您认为适合您的应用程序的方式实现。

如前所述,您还可以对参数使用另一个类,但这只会将设置参数的麻烦转移到其他地方。

于 2014-06-19T13:37:47.010 回答