简体   繁体   English

Java - 使用相同数据类型的多个构造函数

[英]Java - Multiple constructors using same data type

How can we create constructor, to set different values that are from same data type? 我们如何创建构造函数,设置来自相同数据类型的不同值?

Its impossible two create two identical constructors: 它不可能两个创建两个相同的构造函数:

public User(int age, String name){
}  
public User(int age, String surname){
}

User user1 = new User(33, Jack ); 用户user1 =新用户(33, 杰克 );
User user2 = new User(33, Sparrow ); 用户user2 =新用户(33, Sparrow );

Since both name and surname are from same data type, its impossible to know which value the user has meant to set. 由于name和surname都来自相同的数据类型,因此无法知道用户要设置的值。


We can create a constructor that has all the properties and then pass null for unset arguments. 我们可以创建一个包含所有属性的构造函数,然后为unset参数传递null。

public User(int age, String name, String surname){
}  

User user1 = new User(33, Jack ); 用户user1 =新用户(33, 杰克 );
User user2 = new User(33, null, Sparrow ); 用户user2 =新用户(33,null, Sparrow );


There is a way to make it, using HashMap imitating the javascript object literal. 有一种方法可以使用HashMap模仿javascript对象文字。

package javaapplication;

import java.awt.Color; 
import java.util.HashMap;

public class JavaApplication {

    public static class User {

        public int age;
        public String name;
        public String surname;
        public Color hairColor;

        public User(HashMap<String, Object> arguments) {

            if (arguments.containsKey("hairColor")) {
                this.hairColor = (Color) arguments.get("hairColor");
            }

            if (arguments.containsKey("name")) {
                this.name = (String) arguments.get("name");
            }

            if (arguments.containsKey("surname")) {
                this.surname = (String) arguments.get("surname");
            }

            if (arguments.containsKey("age")) {
                this.age = (int) arguments.get("age");
            }
        }
    }

    public static void main(String[] args) {

        User jack1 = new User(new HashMap<String, Object>() {
            {
                put("hairColor", Color.RED);
                put("name", "Jack");
                put("age", 33);
            }
        });
        System.out.println(jack1.hairColor);  // java.awt.Color[r=255,g=0,b=0]
        System.out.println(jack1.surname);    // null
        System.out.println(jack1.name);       // Jack
        System.out.println(jack1.age);        // 33

        User jack2 = new User(new HashMap<String, Object>() {
            {
                put("hairColor", Color.RED);
                put("surname", "Sparrow");
                put("age", 33);
            }
        });
        System.out.println(jack2.hairColor);    // java.awt.Color[r=255,g=0,b=0]
        System.out.println(jack2.surname);      // Sparrow
        System.out.println(jack2.name);         // null
        System.out.println(jack2.age);          // 33

    }

}

Is there a more elegant way to do it? 有更优雅的方式吗?

The typical ways of doing this are with static creation methods or a builder object. 执行此操作的典型方法是使用静态创建方法或构建器对象。

Static creation methods are the way to go if there are distinctive patterns of usage. 如果存在独特的使用模式,静态创建方法就是可行的方法。 For your example (where this perhaps isn't the case). 对于你的例子(这可能不是这种情况)。

public static User ageName(int age, String name) {
    ...
}  
public static User ageSurname(int age, String surname) {
    ...
}
...

In general it's a good idea to avoid any overloading. 一般来说,避免任何超载是个好主意。 With constructors Java rather forces you into it, but sometimes you have to break free. 使用构造函数Java而不是强迫你进入它,但有时你必须打破自由。

Builder may go something like: 生成器可能会像:

public class UserBuilder { // This could be made a nested class of User
    private int age = -1;
    private String name;
    private String surname;
    private Color hairColor;

    public UserBuilder age(int age) {
        this.age = age;
        return this;
    }
    // ... other properties ...
    public User build() {
        // Or return new User(this)
        return new User(age, name, surname, hairColor);
    }
}

This uses the typical Java dirty hack of returning this in a builder so you can build a train wreck. 这使用典型的Java脏黑客在建造者中返回this ,这样你就可以建立一个火车残骸。

User user1 = new UserBuilder().age(33).name("Jack").build();

You really need real examples of usage to see how it should fit in. 您真的需要真实的使用示例来了解它应该如何适应。

You are over-complicating things by using a HashMap here. 在这里使用HashMap使事情过于复杂。 Instead you could make use of the Builder Pattern for the same. 相反,你可以使用Builder模式

class User {
    // required parameters
    private int age;

    // optional parameters
    private String name;
    private String surname;

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public String getSurname() {
        return surname;
    }

    private User(UserBuilder userBuilder) {
        this.age = userBuilder.age;
        this.name = userBuilder.name;
        this.surname = userBuilder.surname;
    }

    public static class UserBuilder {
        // required parameters
        private int age;

        // optional parameters
        private String name;
        private String surname;

        public UserBuilder setName(String name) {
            this.name = name;
            return this;
        }

        public UserBuilder setSurname(String surname) {
            this.surname = surname;
            return this;
        }

        public UserBuilder(int age) {
            this.age = age;
        }

        public User build() {
            return new User(this);
        }

    }
}

Now you can use it : 现在你可以使用它:

User user1 = new User.UserBuilder(12).setName("Jack").build();
User user2 = new User.UserBuilder(12).setSurname("Sparrow").build();

This assumes that age is a mandatory field, name and surname are optional fields for creating an object of User . 这假设age必填字段, namesurname是用于创建User对象的可选字段。 You can tweak it as per your requirement accordingly. 您可以根据您的要求进行相应的调整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM