Java约定:在类中使用getters / setter?
我的教授确实强调通过使用访问器和增变器来访问私有实例variables来防止隐私泄露; 然而,我必须在课堂上使用class级的getters / setters吗?
举例来说,如果我有以下的课程:
public class Person { private String name; private int age; }
我想为它写一个toString()方法。 我可以写:
public String toString() { return name + " " + age; }
或者我需要做这样的事情:
public String toString() { return this.getName() + " " + this.getAge(); }
你可以做任何一个。 但是,您的教授可能会喜欢使用这些方法,而不是直接访问。 这是为什么。
假设你有这样的课程:
class SomeClass { private int someValue; private String someString; public SomeClass(int someValue, String someString) { this.someValue = someValue; this.someString = someString; } public int someValue() { return someValue; } public int someString() { return someString; } public String toString() { return someValue + ": " + someString; } }
这很简单,对吧? 那么,如果突然之间我们想要改变我们如何计算someValue
的实现,并且基于someString
:
public int someValue() { int value = 0; for(int i = 0; i < someString.length; i++) { if(someString.charAt(i) == ' ') value++; } return value; }
现在你也必须改变每个使用了variablessomeValue
地方。
所以,如果您想要使代码更容易维护,请使用方法调用。 这样,当你对你进行编码修改(并相信我,它总是改变),你只需要在一个地方,而不是两个。
是的,你会想要使用方法调用获取someString
而不是在最后一个方法的直接访问:-)
当我devise一个class级的时候,我试图明确区分内部(实施细节)和外部(暴露在世界的界面)。 在内部使用getter和setter会把这些弄糟,因为他们会被内部和外部使用。
如果你发现自己想要从同一class级的另一部分隐藏class级的一部分,可以考虑把你想隐藏的部分拆分到自己的class级中。
这通常不是一个好主意,原因如下:
- 你可能甚至不需要所有领域的访问者
- 一些访问者可能会做一个防御性的副本,所以不暴露内部状态,这通常是不需要的,你知道你不会修改它 – 或者如果你知道你会修改它
- 它使debugging更烦人,因为你必须遵循getters / setters
- 这使得在大多数IDE中阅读代码变得更困难,因为它们中的大多数与本地variables的颜色不同
但是一如既往,也有例外。 一些制作者可能会有副作用(例如设置第二个值),那么你可能会更好地使用制片人。 另外,如果你devise你的类inheritance,如果你希望子类能够改变行为,最好通过访问器。
一般来说,没有。 如果你的getter返回的不是字段值,那么你应该使用这个方法,但在这种情况下,你的方法应该有一个更具描述性的名字。 举个不好的例子,如果你有:
public void setName(String name) { _name = name; }
你的getter返回了其他东西,比如
public String getName() { return _name.toUpperCase(); }
那么是的,你应该使用吸气剂。 尽pipe如此,为这个获得者提供一个更具描述性的名字会更好:
public String getNameAsUppercase() { return _name.toUpperCase(); }
不,你不知道。 您可以从课程中访问任何variables,包括私人,公共或受保护的variables。
这里有一些表格可以帮助你:
来源:Java教程
你可以使用访问器和增变器,但是要遵循一个混乱的标准。
它混淆了你的代码,并混淆了所有试图阅读它的人,因为它可能不属于你的类。
基本上,只需从类内部直接访问variables,并间接从其他地方访问variables。
另一方面,从devise的angular度考虑。 getter / setter的动机之一是基础数据存储可以改变,实现这个类的东西不需要改变,因为它是封装的。
所以,牢记这一点,在课堂上使用getters / setter让未来的变化更容易。 不必直接find改变成员的所有地方,只需要改变getter / setter即可。 根据class级的复杂程度,这可能会显着减less更换存储成员所需的工作量。
例如,让我们假设你从年龄variables开始。 然后你决定以某种原因将其存储为秒。 但是,无论如何,你总是想要打印它。 所以在你的例子中,你可以在你的toString()函数(以及任何需要数年的单位)中进行math计算,或者你可以改变getAge()例程中的math运算,改变。
显然,这个例子有点儿微不足道。 类越复杂,在其中使用getter / setter越有用。
如果你的类(或者所讨论的访问器方法)不是final
,那么你应该使用访问器方法。
如果另一个类扩展你的并覆盖这些访问器,你的类应该使用被覆盖的访问器。 如果这会打破你的超类,那么你的超类devise不正确; 防止这些访问者被final
覆盖,或者改变你的类的devise。
不,你可以直接在类中使用你的实例variables,你没有违反任何“规则”。 getter和setter对于其他类来说是强制性的,以访问类的实例variables而不违反封装原则(这在OO编程中是非常重要的)。
最后,这是一个select的问题,但是你正在使用你的第一个例子保存一个方法调用。
我认为我们应该使用getters()和setters()来代替直接访问。 这也使得debugging非常容易。 例如,如果您需要在class级中指定一个variables多个位置,然后您想从variables分配的位置find多个位置,则需要find所有的赋值并设置断点。
但是如果使用setter,则可以简单地在setter方法中放置一个断点,并可以看到该variables分配了多less次。
如果存在getter和setter,那么即使在课堂上也应该始终使用。 当然,如果getter和setter在方法上做了更多的事情,那么如果满足了需求,就必须考虑它。
应该使用不是指必须使用。 属性可以直接使用(如果属性是私人的,只能在类中使用),但最好使用getter和setter。
所以直接使用财产是可能的,但我build议使用get
和set
因为它给予更多的灵活性,可以做比tipical分配或获得更多的东西。
例如,如果在第一个位置setter只设置的东西,但一段时间后setter被改变做更多的事情。
setName(name){ this.name=name; }
所以在代码setName("John");
是平等的name="John"
。 但想象一下,在设置name
后,我们想要设置另一个属性:
setName(name){ this.name=name; this.nameIsSet=true; }
另一个例子(听众模式) :
setName(name){ this.name=name; this.listener.nameChanged(this.name); //we call listener that variable changed }
然后程序员需要在类中find类似name="John"
每个分配,并将其重构为新的行为。 如果只使用setName
,则不需要更改代码。
当然,一切都取决于需要,可能的设置,从外部获得财产做更多和不同的事情,它不满足我们在课堂上的需要。