例如,我有一个有两个字符串的类,其中一个必须设置,另一个可以为null:
public class SomeClass{
private String s1;
private String s2;
...
}
Run Code Online (Sandbox Code Playgroud)
我可以定义一个构造函数如下:
public SomeClass(String s1, String s2){
if(s1 == null && s2 == null) throw new SomeKindOfException("can't both be null");
this.s1 = s1;
this.s2 = s2;
}
Run Code Online (Sandbox Code Playgroud)
我宁愿做一些事情:
public SomeClass(String s1){
this.s1 = s1;
}
public SomeClass(String s2){
this.s2 = s2;
}
Run Code Online (Sandbox Code Playgroud)
这显然无法工作,因为它定义了两个采用相同数量和类型的参数的方法.
所以,我想做的事情如下:
public SomeClass(SomeTypeOfString s1){
this.s1 = s1;
}
public SomeClass(AnotherTypeOfString s2){
this.s2 = s2;
}
Run Code Online (Sandbox Code Playgroud)
这具有额外的优点,即String的"类型"可以验证它们的内容(例如,SomeTypeOfString必须是6个字符长,而AnotherTypeOfString必须在4到8个字符长之间并且仅包含字母数字字符.
此外,它在调用函数时更清楚,应传入哪些数据.
首先,这个概念听起来合情合理吗?
在实现方面,您无法扩展String.你可以把它包起来.String的"类型"本质上是String的类型,因此让它们扩展抽象包装类是有意义的.这可以实现如下:
public abstract class StringWrapper{
private final String string;
public StringWrapper(String string){
this.string = string;
}
public String getString(){
return string;
}
}
public class SomeTypeOfString extends StringWrapper{
public SomeTypeOfString(String string){
super(string);
}
}
Run Code Online (Sandbox Code Playgroud)
SomeTypeOfString类的代码看起来相当愚蠢,因为它所做的只是定义一个调用超类构造函数的构造函数......但假设你还在那里添加了一些验证,对我来说它看起来很合理.这种实现听起来合理吗?
谁能想到一个更好的概念来解决基本问题,或者更好地实现我概述的概念?
您可以使用构建器.即
public SomeClassBuilder {
String s1;
String s2;
public SomeClassBuilder someString1(String s) {
this.s1 = s;
return this;
}
public SomeClassBuilder someString2(String s) {
this.s2 = s;
return this;
}
public SomeClass build() {
SomeClass sc = new SomeClass();
// if one of s1 or s2 must be null, or you have some other sort of validation, you could do that here, e.g.
if (s1 != null && s2 != null) throw new RuntimeException("not what I expected");
else if (s1 == null && s2 == null) throw new RuntimeException("at least set one value");
sc.setS1(s1);
sc.setS2(s2);
return sc;
}
}
Run Code Online (Sandbox Code Playgroud)
用法是:
SomeClass sc = new SomeClassBuilder().someString1("xxx").someString2("yyy").build();
Run Code Online (Sandbox Code Playgroud)
要么:
SomeClass sc = new SomeClassBuilder().someString2("abc").build();
Run Code Online (Sandbox Code Playgroud)
对于仅两个构造函数参数,益处相对较小,但随着输入的增加,可读性益处增加.