Java 我应该使用超类';setters从子类初始化其实例变量?

Java 我应该使用超类';setters从子类初始化其实例变量?,java,inheritance,Java,Inheritance,我有一个超类“Vehicle”和它的子类“Car”,如下所示。我想初始化子类Car的构造函数中的变量wheels。我无法通过super()调用设置变量,因为它依赖于对方法的调用 在这里使用超类的setter方法安全吗? 如果没有,类之间关系的OO基础是否存在问题 另外,请尝试为笨拙的车辆/汽车/底盘示例辩解,并假设在构造函数之外调用“findNumberOfWheels”方法是必要的 车辆等级 public abstract class Vehicle { private int wh

我有一个超类“Vehicle”和它的子类“Car”,如下所示。我想初始化子类Car的构造函数中的变量wheels。我无法通过super()调用设置变量,因为它依赖于对方法的调用

在这里使用超类的setter方法安全吗? 如果没有,类之间关系的OO基础是否存在问题

另外,请尝试为笨拙的车辆/汽车/底盘示例辩解,并假设在构造函数之外调用“findNumberOfWheels”方法是必要的

车辆等级

public abstract class Vehicle {

    private int wheels;
    private Chassis chassis;

    public Vehicle(Chassis chassis){
       this.chassis = chassis;
    }

    public int getWheels() {
       return wheels;
    }

    public void setWheels(int wheels) {
       this.wheels = wheels;
    }

    public Chassis getChassis() {
       return chassis;
    }

    public void setChassis(Chassis chassis) {
       this.chassis = chassis;
    }

}
汽车等级

public class Car extends Vehicle{

    public Car(Chassis chassis) {
        super(chassis);
        setWheels(findNumberofWheels(chassis));
    }

    private int findNumberofWheels(Chassis chassis){
        return chassis.getWheels();
    }

}

如果您可以通过子类构造超类,那么您肯定可以使用它的setter

我猜您的替代方案是将这些调用移到构造函数之外,并在每次实例化新的
汽车时调用
setWheels
?你肯定不想这样做,因为你会重复你自己,而你(或其他人)可能会忘记打电话。您应该将尽可能多的初始化代码放入构造函数中。这样,如果你需要改变它,你只需要在一个地方改变它

您甚至可以将“超类”字段设置为“受保护”:

protected int wheels;
直接改变它。但这取决于您自己的判断。

findNumberOfWheels()
在我看来是一种实用方法,因为它既不使用
车辆
也不使用
汽车
类的任何属性

如果实际情况是这样,则应在
Car
类或其他地方声明它为
static
。如果它是
静态的
,您可以在对
super()
的调用中内联它的调用,并将其作为参数传递给超类的构造函数,因此我认为没有必要调用setter

通常,如果在分配变量之前需要进行一些计算,则通过构造函数初始化属性并委托给实用工具方法更安全


如果不可能,请使用factory或builder模式。

没关系,您不需要重写子类上的getter/setter,因为它的行为方式相同。如果有人调用
Car.setWheels(70)
?如果可能的话,您应该避免向基类型的接口添加变体。通过构造函数注入车轮的数量,并使属性
成为final
将更加安全。请查看Jon Skeet对此主题的看法:
findNumberOfWheels()
对我来说似乎是一种实用方法,因为它既不使用
车辆
也不使用
汽车
的任何属性。如果实际情况是这样,那么应该在
Car
类或其他地方将其声明为静态。如果它是静态的,您可以在调用
super()
时内联调用它,并将其作为参数传递给超类的构造函数,因此我认为没有必要调用setter,因此这是一个委托案例。在Car和vehicle中维护重复属性没有意义您是对的,我不想将其移到构造函数之外,因为我确实会忘记调用。正如@Magnamag指出的,“findNumberofWheels()”实际上是一种实用方法,可以避免将代码直接放入构造函数中,因此应该声明为静态。谢谢你的帮助。