Java 组成 - 构造函数

Java composition - Constructor

今天遇到了作文。据我了解,对于每个组合实例,我都需要在构造函数中创建新对象,如下所示:

public class Human {
   private String name;
   private Adress adress;

   public Human (String name, Adress adress) {
      this.name = name;
      this.adress = new Adress(adress);
   }
}

因此,如果我要创建一个 class human 的新实例,我需要为其分配一些地址实例,或者创建全新的地址,构造函数将如下所示

public class Human {
   private String name;
   private Adress adress;

   public Human (String name, String city, String country) {
      this.name = name;
      this.adress = new Adress(city, country);
   }
}

首先,这些代码是否正确?还有什么选项,如果我要创建 class human 的新实例,属性 Adress 将为空,我可以稍后使用 set 方法设置它? 非常感谢您的回复。

一个新对象一般来说不是强制性的,但是,如果你想要人类不可变的地址(只有当地址已经不可变时),最好从外部杀死所有对它的引用对象。

确实是作文的规律

如果 address 在其构造函数中将地址作为输入,这自然是这样做的方法。

public class Human {
    private String name;
    private Adress adress;

    public Human (String name, Adress adress) {
        this.name = name;
        this.adress = new Adress(adress); 
    }
}

如果你愿意,你可以有一组不同的构造函数并稍后设置一些字段

public class Human {
    private String name;
    private Adress adress;

    public Human() {}
    public Human(String name){
        this.name = name;
    }
    public Human(String name, Adress adress) {
        this.name = name;
        this.adress = adress; // or new Adress(adress)
    }

    public void setAdress (Adress adress) {
        this.adress = adress;
    }
}

如果我对你的问题理解正确,那么你正在寻找 default constructorgetter-setters 作为姓名和地址。

这是代码片段:

public class Human {

    private String name; 
    private Address address;

    /* Default Constructor */
    public Human() {}

    public Human(String name, Address address) {
        this.name = name;
        this.address = new Address(address); 
    }

    /* Getter for Name */
    public String getName() {
        return this.name;
    }

    /* Setter for Name */
    public void setName(String name) {
        return this.name = name;
    }

    /* Getter for Address */
    public Address getAddress() {
        return this.address;
    }

    /* Setter for Address */
    public void setAddress(Address address) {
        return this.address = address;
    }
}

现在,您可以轻松地创建 class Human 的新对象,方法是:

Human h = new Human();

然后按如下方式设置名称或地址:

h.setName("foo");
h.setAddress(new Address("foo","bar"));

请注意,我已修复 adress 中的拼写错误。

两个都是正确的。

但我更喜欢第一个,因为您使用的是您的 class 地址,该地址包含在人类 class 中。

public class Human {
    private String name;
    private Adress adress;

    public Human (String name, Adress adress) {
        this.name = name;
    this.adress = new Adress(adress); 
    }
}

First of all, are those codes correct?

正确是什么意思?它会为你编译吗?如果是这样,那么他们是(不是真的,但至少在那个意义上)。

is there any option, that if I would create new instance of class human, the attribute Address would be empty, and I could set it later by using set method?

是的,您可以通过多种方式实现这一点,其中之一是添加适当的构造函数:

public Human (String name) {    
    this.name = name;
}

并添加 setter:

private void setAddress(Adress adress) {    
    this.adress = adress;    
}

您可以创建一个新的 Human 对象,并将 Address 参数设置为 null:

Human human = new Human("My Name", null, null);

但是你必须检查这些参数并将 address 设置为 null 如果它们(或其中之一)是 null.

或者您可以在 Human class:

中定义一个新的构造函数
public Human(String name) {
    this.name = name;
    /* The line below is not required, since objects are set to null by default*/
    this.address = null;
}

并且您可以创建一个 setter 方法,仅当地址本身为 null 或地址参数为 null 时才允许更改地址。也就是说,如果那是你想要的。
下面是一个示例:

public void setAddress(Address address) {
    if (this.address == null) {
        this.address = address;
    }
}

Address 通常不止于此:街道 1、街道 2、城市、州、县、邮政编码、邮政编码扩展、国家/地区、lat/lon 等。我会考虑您的例子不充分。

一个对象在构建时应该 100% 准备就绪。您可以重载构造函数或提供构建器以方便使用。

此规则的一个例外是 JSON 与 Jackson 的连载。它需要一个无参数构造函数和所有序列化私有数据成员的 getter/setter 对,因为它使用反射和 Java Bean 约定。

没有对与错,正确与不正确。在提高可读性、清晰度、易用性和更改性以及保持 DRY 的同时,有些方法适用于您的代码。

还有一点建议:名字很重要。仔细想想他们。 Human真的?除非你打算有非人类的替代品,否则我会说 PersonIndividualCustomer 或适合你的上下文的东西是更好的选择。

还有一个:一个 Person 可以有多个 Address 吗? ResidenceMailingShippingGaraging 等?你将如何处理?