示例:
private int x = 4;
public TestClass(int x) {
this.x = x;
}
public TestClass(int x) {
setX(x);
}
public void setX(int x) {
this.x = x;
}
第一个构造函数是更好的练习还是第二个?我之所以这样问,是因为如果我之前使用IntelliJ IDEA
我将我的课程封装在this.x = x
中,则会将其更改为setX(int newX);
。
答案 0 :(得分:1)
在大多数情况下,这都是个人喜好。如果它的值不依赖于其他变量,我会使用第一个构造函数。但是,setter方法允许在修改变量值之前满足某些条件。例如:
private int x;
public TestClass(int x) {
setX(x);
}
public void setX(int x) {
// Some random condition depending on other variables.
if (System.currentTimeMillis() & 1 == 0) {
this.x = 5;
} else {
this.x = x;
}
}
如果有许多条件无法用三元语句轻易表示,那么使用setter方法是有意义的。
如果类是抽象的,那么扩展它的具体类可能会覆盖setter方法,从而修改变量的值。如果您打算使用自封装并且不希望任何子类覆盖setter方法,只需将final
关键字添加到方法声明中。
答案 1 :(得分:1)
取决于。
派生类可以覆盖setter,你需要决定覆盖的效果在特定位置是好还是坏。
我的观点是,如果记录的setter是可覆盖的,则需要注意使用setter与赋值。如果您没有将setter文档记录为可覆盖,那么只需使用赋值。
答案 2 :(得分:0)
有一个名为# command line args
printfLR foo bar
# stdin
fortune | tr -s ' \t' '\n\n' | paste - - | printfLR
的术语。 Martin Fowler写了一篇关于这个主题的博客。 Blog Link。总结一下,您可能会在function s2n(s) {
var pow, n = 0, i = 0;
while (i++ < s.length) {
pow = Math.pow(26, s.length - i);
var charCode = s.charCodeAt(i - 1) - 96;
n += charCode * pow;
}
return n;
}
function n2s(n) {
var s = '';
var reduce = false;
if (n === undefined) {
n = 0;
} else {
n--;
}
while (n !== undefined) {
s = String.fromCharCode(97 + n % 26) + s;
n = Math.floor(n / 26);
if (n === 0) {
n = undefined;
} else {
n--;
}
}
return s;
}
中进行初始化或分配逻辑。所以我认为,无论何时初始化或分配值,最好都要调用Self Encapsulation
。
答案 3 :(得分:0)
你已经接受了答案,但我仍然看到没有人提到的事情。一个setter使你的类可变(至少没有保护条件),这可能是也可能不是一件好事。但是,如果将值提供给构造函数,则使类不可变更容易。
不可变类本质上是线程安全的,并且在实际应该是首选。所以在你的(不可否认的是简单的)例子中,我倾向于使用构造函数,而我只有一个getter用于值。
IMO,拥有一个带有值的构造函数和一个设置相同值的setter是一个代码香气,如果没有气味。