关于构造函数

时间:2010-01-18 09:59:32

标签: c# java constructor

我有一个关于Constructors的问题。我认为构造函数只是我们的方便而不是setter方法,对吧?因此,对于一个对象,您认为重要的属性(例如webform中的必需字段)将作为参数传递给构造函数。

是否有任何标准要将这么多参数传递给构造函数? 请详细说明这些要点以及关于构造函数的任何要点。

编辑:对于我问问题的方式很抱歉。是的,我们使用构造函数创建一个对象,我们使用setter赋值,但我的问题是默认构造函数与setter和构造函数之间的比较parametrs。

7 个答案:

答案 0 :(得分:11)

不,这不仅仅是一种方便,而不是制定者。特别是,构造函数只会被称为一次。使用构造函数参数,您可以创建在构造时赋予其值的不可变类型 - 这对于setter是不可能的。

拥有巨大的数量的参数通常不是一个好主意,无论是构造函数还是普通方法。如果您发现有很多参数,可能想要创建一个代表所有相关参数的类型 - 类型可能有一堆getter / setter。有关此示例,请参阅ProcessStartInfo

答案 1 :(得分:10)

我这样看:

您在构造函数中传递参数,以便创建处于“有效”状态的对象。

对于您的示例:我不会将“webform中的必填字段”传递给填充了这些值的类的实例。

答案 2 :(得分:4)

您必须在对象上调用setter ,构造函数创建该对象。如果没有构造函数调用,您将无法调用对象。

重新。参数的数量。如果您有相当多的参数,则表明:

  1. 相关参数可以组合成对象本身。例如TimePeriod对象的开始日期和结束日期
  2. 该对象责任太多,应该进一步分解
  3. 查看Factory模式和Builder模式以了解其他选项。创建对象。

    进一步说明。构造函数参数和setter。在Java和C#中,传递给构造函数的参数只能用于初始化字段一次,并且字段从该点开始是不可变的(与通过setter设置这些字段时不同)。这对代码可靠性有很大好处(以对象不变性为代价)。

答案 3 :(得分:3)

构造函数用于初始化类。您应该将所需的参数传递给所需的初始状态。

请注意,您也可以重载构造函数。

答案 4 :(得分:2)

如果您有一些非可选参数和许多可选参数,并且您希望避免构造函数中的looong参数列表(这可能非常容易出错,特别是如果参数类型相同),您应该支持

的使用

Builder pattern

代替。

答案 5 :(得分:0)

您还可以考虑使用Factory pattern来创建对象。

答案 6 :(得分:0)

我认为在决定如何创建对象时,应该更加注意对象的部署位置。我尝试总结一些有助于选择用于填充对象字段的方法的点,即构造函数或setter方法:

  • 状态:按状态,我指的是运行时快照中对象的所有字段的值。在开发应用程序时,跟踪对象状态非常重要,尤其是在要在多个线程中访问对象时。即使在单线程编程中,也可以在不同的方法和类中修改对象,尤其是在通过引用传递所有对象的Java等语言中。一次性设置状态(在构造函数中)和避免setter(称为不可变模式)使得编程,尤其是并发编程变得非常容易。但请注意,这种方法会增加对象修改成本,因为在每次修改时都应将所有字段复制到新实例中;例如,在Java中,将String(不可变)与StringBuilder和StringBuffer(有状态)进行比较。 String是线程安全且易于使用的,但是对于长字符串创建来说代价很高,而StringBuilder不是线程安全的,但是连接小字符串很快。同时,StringBuffer既是有状态又是线程安全的,但在每个方法调用中都很昂贵,因为它的方法是 synchronized (这意味着:当大多数情况下不需要时,不要使有状态对象成为线程安全的用例)。因此,作为一般提示:对于在多个线程中访问的对象使用构造函数(和不可变模式),并使用setter来处理受更多控制的本地对象和字段。

  • 注入:当我们使用依赖注入框架(例如SpringGuice)时,框架使一种方法比另一种更优选。例如,spring比构造函数注入更能鼓励setter注入。 Spring主要使用默认构造函数构造对象(bean),然后使用setter方法注入依赖项。然后Spring为您调用init(PostConstruct)方法。因此,您可以使用就地依赖项在此方法中执行所需的任何初始化。相反,Guice鼓励将构造函数注入作为其最佳实践。

  • 代码之美:不仅在构造函数中有很长的参数列表也不漂亮,而且如果应该重载许多其他构造函数来支持多个可选参数,这些构造函数可能会由于具有相同的参数类型而发生冲突。因此,如果许多字段是可选的,则使用setter会更有效。但我认为即使在这种情况下,对象使用场景也更为重要。如其他开发人员在此处所建议的那样,可以通过将参数分组在其他类中来解析长参数列表。

  • new 或To Delegate:无论何时使用构造函数或setter方法填充“ new ”这些领域,如果有人在某天需要通过(注入,创造)它,这是一个很好的做法。这导致了Factory设计模式,这在开发工具和库时特别有用。