Setter方法或构造函数

ssa*_*yed 39 java setter constructor

到目前为止,我已经看到了两种在Java中设置变量值的方法.有时使用带参数的构造函数,其他setter方法用于设置每个变量的值.

我知道一旦使用"new"关键字对类进行实例化,构造函数就会在类中初始化一个实例变量.

但是我们何时使用构造函数,何时使用setter?

Sud*_*hul 46

当您想要创建对象的新实例时,应该使用构造函数方法,并且已经填充了值(填充了值的即用型对象).这样,您无需为对象中的每个字段显式调用setter方法来填充它们.

在创建对象后,如果要更改字段的值,可以使用setter方法设置值.

例如:-

MyObject obj1 = new MyObject("setSomeStringInMyObject"); // Constructor approach
// Yippy, I can just use my obj1, as the values are already populated
// But even after this I can change the value
obj1.setSomeString("IWantANewValue"); // Value changed using setter, if required.
..
MyObject obj2 = new MyObject();
obj2.setSomeString("setSomeStringNow"); // Setter approach
// values weren't populated - I had to do that. Sad :(
Run Code Online (Sandbox Code Playgroud)

正如Axel所提到的,如果你想创建不可变对象,你就不能使用setter-methods方法.我不会说必须在构造函数中初始化所有内容,因为存在不同的方法,例如即使对于不可变对象也可以使用的惰性求值.

  • +1并且如果你想创建不可变对象,你不能使用setter-methods(我不会说所有东西都必须在构造函数中初始化,因为存在不同的方法,比如懒惰评估,甚至可以用于不可变对象). (3认同)
  • 假设您的班级有 20 个奇数字段。该应用程序要求您使用仅 5 个用于创建对象的必填字段快速创建该类的新对象。有一个只有这 5 个字段的构造函数,并且对象实例化已经完成。现在在应用程序的后面,有一段代码可以执行一些业务逻辑来设置/重置其他字段。在这种情况下,您将需要这些字段的设置器。这只是一个简单的案例,有很多情况可以将两者结合起来。您对需求的评估应该是决定性因素。 (2认同)

S. *_*yol 8

我想你问了一个很好的问题: - 但是我们什么时候使用构造函数?什么时候使用setter?

首先,让我们从一些概念开始.我希望这个解释可以帮助每个想知道何时使用构造函数或setter()和getters()方法(Accessors和Mutators)的人.构造函数Methods类似,但java中构造函数方法之间的差异很小:

1)构造函数用于初始化对象的状态. 方法用于公开对象的行为.

2)构造函数不能有返回类型.方法必须具有返回类型.

3)隐式调用构造函数.方法被显式调用.

4)Getters()或访问器是提供对对象实例变量的访问的方法.Setters()或mutators是为调用者提供更新特定实例变量值的机会的方法.

有了这个清楚,让我们考虑面向对象编程(OOP),以满足OOP主体的要求(面向对象编程(OOP)构建超过四个主要原则:封装,数据抽象,多态继承.),Getter ()Setter()方法是实现这一目标的关键.

这是一个公式,将向您展示我的意思:

私有字段+公共访问者==封装;

正如您在设置私有字段和使用公共加密器时基于此公式所看到的,我们正在执行4个OOP主体之一的封装.

在这里,我将为您提供两个课程,我添加了评论,试图让我的代码自我解释.将这些类作为方法的实验室CustomerTestCustomer[ main()方法]类的方法,您可以复制代码并自己运行它.注意我使用了两个构造函数来解释一个具有多个构造函数并具有public setters()getters()方法的类,以便访问私有实例变量:

package com.exercise.lecture2;

/**
 * 1) Create a Customer class that has the following attributes:
 * name, SSN.
 * 2) This class should have two methods: getName() and getSSN().
 * 3) If the class is instantiated with only a SSN, then give the default name of "John Doe". (HINT: Use two constructors)
 * 4) Also, add a method toString(), that returns a string representation of the customer object (name and SSN concatenated).
 *      Make sure to set this method public.
 * 5) Create a class to test your program (e.g. a class that include the main() method). In your test program, instantiate
 *      three customers and print out the value using toString() method.
 * 
 * @author Samuel M.
 *
 */

//this class is complemented with class  TestLabCustomer.java
public class LabCustomer {

// Private filds: name and socialSecurityNum
    private String name;
    private int socialSecurityNum;

    // constructors
    public LabCustomer(String name, int socialSecurityNum) {
        this.name = name;
        this.socialSecurityNum = socialSecurityNum;
    }

    /** The keyword 'this' can be used to call a constructor from a constructor,
     * when writing several constructor for a class, there are times when
     * you'd like to call one constructor from another to avoid duplicate code.
     */
    // Account with This() on a second constructor
    public LabCustomer(int socialSecurityNum) {
        this("John Doe", socialSecurityNum); // default name is printed if only the SSN is provided
    }

    // Public accessors (getters and setters)
    String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }

    int getSSN() {
        return socialSecurityNum;
    }

    void setSSN(int socialSecurityNum) {
        this.socialSecurityNum = socialSecurityNum;
    }


    // instance method
    public String toString() { //overriding the toString() method 
        return ("Customer name: " + getName() + ", SSN#: " + getSSN() ); // concatenating the name and SSN

    }
}
Run Code Online (Sandbox Code Playgroud)

这是测试类,它具有main()方法并在实例化预览类的对象后调用实例方法:

package com.exercise.lecture2;

//this class is complemented with class  LabCustomer.java
public class TestLabCustomer {

    public static void main(String[] args) {
        // Instantiating an object of class LabCustomer and creating three customers objects
        LabCustomer cust1 = new LabCustomer("Juan Melendez", 123457789);
        LabCustomer cust2 = new LabCustomer("Mary Lee", 125997536);
        LabCustomer cust3 = new LabCustomer(124963574); // when instantiating with no "name", the default (John Doe) is printed 

        /**
         * Once you've instantiated an object and have an object variable,
         * you can use object variable to call an instance method. 
         *  e.g.:
         *  object variables: cust1, cust2, cust3
         *  call the method toString() using the object variable and dot [.] in order to perform the method call.
         */
        // calling method toString() in class LabCustomer to print customer values
        System.out.println(cust1.toString());
        System.out.println(cust2.toString());
        System.out.println(cust3.toString());

    }

}
Run Code Online (Sandbox Code Playgroud)

结果:

客户名称:Juan Melendez,SSN#:123457789

客户名称:Mary Lee,SSN#:125997536

客户名称:John Doe,SSN#:124963574


Evg*_*eev 7

如果你想要一个不可变的类使用构造函数,否则使用 setter。

  • @ZhekaKozlov 如果一个对象具有改变状态的 setter,那么根据定义,该对象不是不可变的,对吗? (2认同)

Rav*_*abu 7

简单来说:

如果您认为在使用对象之前必须进行初始化,请使用构造函数。

当变量的初始化不是必须使用对象时,请使用setter方法。

有关更多详细信息,请参阅文档页面