Java 我应该使用超类';setters从子类初始化其实例变量?
我有一个超类“Vehicle”和它的子类“Car”,如下所示。我想初始化子类Car的构造函数中的变量wheels。我无法通过super()调用设置变量,因为它依赖于对方法的调用 在这里使用超类的setter方法安全吗? 如果没有,类之间关系的OO基础是否存在问题 另外,请尝试为笨拙的车辆/汽车/底盘示例辩解,并假设在构造函数之外调用“findNumberOfWheels”方法是必要的 车辆等级Java 我应该使用超类';setters从子类初始化其实例变量?,java,inheritance,Java,Inheritance,我有一个超类“Vehicle”和它的子类“Car”,如下所示。我想初始化子类Car的构造函数中的变量wheels。我无法通过super()调用设置变量,因为它依赖于对方法的调用 在这里使用超类的setter方法安全吗? 如果没有,类之间关系的OO基础是否存在问题 另外,请尝试为笨拙的车辆/汽车/底盘示例辩解,并假设在构造函数之外调用“findNumberOfWheels”方法是必要的 车辆等级 public abstract class Vehicle { private int wh
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()”实际上是一种实用方法,可以避免将代码直接放入构造函数中,因此应该声明为静态。谢谢你的帮助。