Java 无参数构造函数被认为是OOP中的最佳实践吗

Java 无参数构造函数被认为是OOP中的最佳实践吗,java,oop,Java,Oop,在设计类时,我应该努力使构造函数无参数吗?不,一点也不。对于类来说,默认构造函数或“无参数”构造函数通常是一个有用的特性,但只能作为可用构造函数之一,而不是唯一的构造函数。在构造过程中建立对象的重要不变量是一件好事,带参数的构造函数通常是实现这一点的必要部分。不,一点也不。对于类来说,默认构造函数或“无参数”构造函数通常是一个有用的特性,但只能作为可用构造函数之一,而不是唯一的构造函数。在构造过程中建立对象的重要不变量是一件好事,而带参数的构造函数通常是实现这一点的必要部分。我会说不。在使用解耦

在设计类时,我应该努力使构造函数无参数吗?

不,一点也不。对于类来说,默认构造函数或“无参数”构造函数通常是一个有用的特性,但只能作为可用构造函数之一,而不是唯一的构造函数。在构造过程中建立对象的重要不变量是一件好事,带参数的构造函数通常是实现这一点的必要部分。

不,一点也不。对于类来说,默认构造函数或“无参数”构造函数通常是一个有用的特性,但只能作为可用构造函数之一,而不是唯一的构造函数。在构造过程中建立对象的重要不变量是一件好事,而带参数的构造函数通常是实现这一点的必要部分。

我会说不。在使用解耦机制(如依赖项注入)时,构造函数的参数是定义不可变依赖项的最佳位置。同样,对象的任何其他不可变参数都应该放在构造函数中。

我会说不。当使用解耦机制(如依赖项注入)时,构造函数的参数是定义不可变依赖项的最佳位置。同样,对象的任何其他不可变参数都应该放在构造函数中。

。您可以拥有任意多的构造函数,并且不一定需要默认构造函数您的构造函数应该对类的目的有意义,这是唯一的最佳实践。

。您可以拥有任意多的构造函数,并且不一定需要默认构造函数你的构造器应该对课程的目的有意义,这是唯一的最佳实践。

对此有不同的想法。JavaBeans模式需要一个默认构造函数以及getter和setter来完成一个对象。然而,这会导致实例处于不确定状态(有关这方面的更多信息,请参阅Josh Bloch的《有效Java》)


构造函数参数阻止任何形式的“魔法”,因为您需要提供创建类实例所需的实例(也称为依赖项注入)。

对此有不同的想法。JavaBeans模式需要一个默认构造函数以及getter和setter来完成一个对象。然而,这会导致实例处于不确定状态(有关这方面的更多信息,请参阅Josh Bloch的《有效Java》)


构造函数参数阻止任何形式的“魔法”,因为您需要提供创建类实例所需的实例(也称为依赖项注入)。

答案既不是肯定的,也不是否定的:这取决于

通常,参数化构造函数用于初始化具有不可变(
final
)值的对象。我首先想到的是下面的例子

public class Car {
     public Car(String chassisCode) {...}

     public String getChassisCode();

     public String getLicenseNumber() {...}
     public void setLicenseNumber(String value) {...}
}
由于车牌注册号在汽车的生命周期中可能会发生变化,因此可以将其作为get/set属性实现。相反,底盘注册码对于每辆车都是唯一的,不可变。汽车可以随时更改其牌照,但底盘编号是不可变的,并且在牌照或车主更改时随文档一起注册

在其他情况下,您可能需要一个“默认”无参数构造函数来获得类的“默认”行为。一个例子

public class LightSwitch {
    private boolean state = false; //off

    public LightSwitch() {}

    public boolean getState();
    public void setState(boolean value);
}

在这种情况下,除非明确打开电灯开关,否则电灯开关被视为关闭。

答案既不是是也不是:这取决于具体情况

通常,参数化构造函数用于初始化具有不可变(
final
)值的对象。我首先想到的是下面的例子

public class Car {
     public Car(String chassisCode) {...}

     public String getChassisCode();

     public String getLicenseNumber() {...}
     public void setLicenseNumber(String value) {...}
}
由于车牌注册号在汽车的生命周期中可能会发生变化,因此可以将其作为get/set属性实现。相反,底盘注册码对于每辆车都是唯一的,不可变。汽车可以随时更改其牌照,但底盘编号是不可变的,并且在牌照或车主更改时随文档一起注册

在其他情况下,您可能需要一个“默认”无参数构造函数来获得类的“默认”行为。一个例子

public class LightSwitch {
    private boolean state = false; //off

    public LightSwitch() {}

    public boolean getState();
    public void setState(boolean value);
}

在这种情况下,除非明确打开电灯开关,否则电灯开关将被视为关闭。

在断章取义、未完全听到建议或用外语听到建议时,可能是误解。 我怀疑你听到有经验的人说(可能过于强调)类似这样的话:

1) “您应该始终尝试使用无参数构造函数。”

那么你误解了这意味着:

2) “您应该始终尝试只使用无参数构造函数。”

语句(1)是正确的,因为如果在相关类上调用无参数构造函数(或由子类调用),并且如果不存在,则编译器将创建自己的构造函数,代码的行为将很难预测


陈述(2)通常是不正确的。

在断章取义、未完全听到建议或用外语听到建议时,可能是误解。 我怀疑你听到有经验的人说(可能过于强调)类似这样的话:

1) “您应该始终尝试使用无参数构造函数。”

那么你误解了这意味着:

2) “您应该始终尝试只使用无参数构造函数。”

语句(1)是正确的,因为如果在相关类上调用无参数构造函数(或由子类调用),并且如果不存在,则编译器将创建自己的构造函数,代码的行为将很难预测


声明(2)通常是不正确的。

谷歌建议我说“机架号”而不是“机箱号”:你已经给出了最好的解释,但问题的答案是正确的