假设我有一个包含3个字段的类:A,B和C。我可以通过两种方式创建该类的实例:将所有字段传递给构造函数,或者仅传递A,其他属性将基于在A上。
class App extends React.Component {
state = {
value: moment(),
};
handleValueChange = (value, id) => {
console.log(value && value.format('HH:mm:ss'));
console.log(id);
this.setState({ value });
};
clear = () => {
this.setState({
value: undefined,
});
};
render() {
const { value } = this.state;
return (
<div>
<TimePicker
id={item.day}
defaultValue={value}
onChange={(value, id=item.day) => this.handleValueChange(value, id)}
/>
<button onClick={this.clear} type="button">
clear
</button>
</div>
);
}
}
此方法使用两个主要构造函数,而没有主要构造函数。但是从我的角度来看,它看起来很沉重。是否可以用更优雅的方式重写此逻辑?
答案 0 :(得分:3)
也许您可以采取以下措施。您可能希望将Pair
替换为实际类型,然后...
class MyClass(
val A: String,
val BC : Pair<String, String>
) {
constructor(A: String, B: String, C: String) : this(A, B to C) // is this then even needed?
constructor(A : String) : this(A, Calculator.calculate(A))
}
或者,如果更合理的话,则具有三个单独的属性,反之亦然,k0enf0rNL 也显示了这一点:
class MyClass(
val A: String,
val B: String,
val C: String
) {
constructor(A: String) : this(A, Calculator.calculate(A))
constructor(A: String, BC : Pair<String, String>) : this(A, BC.first, BC.second)
}
最后,如果您不想公开某些构造函数,请随意将其标记为private
,例如以下内容将与您显示的示例相同:
class MyClass(
val A: String,
val B: String,
val C: String
) {
constructor(A: String) : this(A, Calculator.calculate(A))
private constructor(A: String, BC : Pair<String, String>) : this(A, BC.first, BC.second)
}
也许您宁愿需要一些东西来传递函数(因为您还使用了Calculator.calculate(A)
)。然后,您可能需要添加以下内容作为构造函数:
constructor(A : String, func: (String) -> Pair<String, String> = Calculator::calculate) : this(A, func(A))
如果这从一开始就是您想要的,那么即使是如下所示的类也可能适合您:
class MyClass(val A: String,
func: (String) -> Pair<String, String> = Calculator::calculate) {
val B: String
val C: String
init {
func(A).also { (newB, newC) ->
B = newB
C = newC
}
}
}
如果您随后只想传递A
,B
和C
而没有实际的计算(或传递的函数),则仍然可以按照以下步骤进行(基本上丢弃传递的{ {1}}):
A
答案 1 :(得分:2)
我个人最喜欢的是滥用伴侣对象调用运算符:
class MyClass(val A: String, val B: String, val C: String) {
companion object {
operator fun invoke(A: String): MyClass {
val (B, C) = Calculator.calculate(A)
return MyClass(A, B, C)
}
}
}
答案 2 :(得分:0)
您可以将其编写为数据类,并且至少可以像这样摆脱默认构造函数
data class MyClass(
val A: String,
val B: String,
val C: String
) {
constructor(A: String, calculated: Pair<String, String> = calculate()) : this(
A,
calculated.first,
calculated.second
)
}
fun calculate() : Pair<String, String> = "this" to "that"