有人可以帮助我理解这一点:
“例如,一个对象的实例变量(非常量的成员字段)应该始终是私有的。期间。没有异常。永远。我的意思是。(您可以偶尔有效地使用受保护的方法,但受保护的实例变量你应该永远不要出于同样的原因使用get / set函数 - 它们只是过于复杂的方式使一个字段公开(虽然返回完整对象而不是基本类型值的访问函数是合理的返回对象的类是设计中的关键抽象的情况。)“ - http://www.javaworld.com/article/2073649/core-java/why-extends-is-evil.html
我不明白他的意思是什么,“你不应该出于同样的原因使用get / set函数 - 它们只是过于复杂的方式使字段公开。”假设我有一个带有Name和Age实例变量的简单Person类。我应该如何将这些提供给其他课程?他的意思是我应该创建一个数据传输对象吗?这是一个正确的实现吗?这是否真的比在Person类中使用getter和setter更好?
public class Person {
private PersonData personData;
public Person (String name, int age){
this.personData =
new PersonData(name, age);
}
// get personData
// person methods...
}
// data transfer object
class PersonData {
private String name;
private int age;
public PersonData(String name, int age){
this.setName(name);
this.setAge(age);
}
// getters and setters ...
}
答案 0 :(得分:1)
对于要向其他对象公开的对象的所有属性,肯定应该有getter。如果你的对象是可变的,你可能想要所有可以修改的属性的setter方法。
set / get方法不 overly complicated ways to make a field public
。它们允许您控制对成员的访问和修改。
例如,如果您的类是不可变的,则返回某个对象的get方法将返回该对象的克隆,以防止调用者对其进行修改。
再举一个例子,如果你的类是可变的,那么setter可以包含你想要设置的新值的验证。
答案 1 :(得分:1)
更多评论回答......
本文致力于确定松散耦合的需求/优势,以及获得它的技术。
其中一点是避免依赖对象的内部数据结构,只使用其运算符。在这一点上,自动使您的状态可访问是不好的,因为使用您的类的对象可能依赖于这些属性而不是使用给予它们的更“精炼”的操作。
根据我对该文章的理解,可能的示例如下:
想象一下Person
类/接口,包含两个操作,例如isOldEnoughToBuyBeer
和isOldEnoughToDriveCars
。
如果您在Person
中为dateOfBirth
创建了一个setter / getter,那么您将绑定Person
的实现以拥有此类属性,并将操作实现为“检查当前date agains dateOfBirth
属性并根据年数返回true“。
当然,声明“你永远不应该出于同样的原因使用get / set函数 - 它们只是过于复杂的方式使字段公开”可能过于严格;虽然它很好地指出即使通过getter / setter进行访问也会产生后果,但很难想象属性只在内部用于持有它们的类。
答案 2 :(得分:0)
作者认为你永远不应该有公共实例变量。 (因为它们破坏了封装,但我相信你并没有因此而停顿 - 如果需要,我们可以实现它。)
当他说 “你不应该出于同样的原因使用获取/设置功能” 他说,实际上,公开get
和{ {1}}实例变量的方法大约set
与变量本身*
的方法相同。
唯一的区别(以及他写“他们只是过于复杂的方式使字段公开”的原因)是,而不是实例变量中的修饰符public
,你创建了两个额外的方法
(数据)转移对象是一种完全不同的动物,它们与所讨论的背景无关。
public
“粗略”因为我们正在讨论getter和setter的(通常)假设,只是读取和写入实例变量,而不是进行任何额外的处理。
答案 3 :(得分:0)
Correct way to expose instance variables to other classes
您应该提供尽可能低的实例字段访问权限。提供访问权限的首选方法是有三个项目
此方法具有以下好处
第一个好处:这种方法可以增加抽象。
假设Name的getter(或accessor)方法定义如下
String getName() {
return name;
}
现在出于某种原因,您希望将名称的实现更改为
String firstName;
String lastName;
在这种情况下,您可以将getName()
更改为
String getName() {
return firstName + " " + lastName;
}
使用这种方法不会破坏您现有的代码,否则很难获得(如果不是不可能)。
第二个好处:您可以一次执行错误检查。
考虑用户输入的年龄是负面或实际上不可能的情况(如99999999)。在这种情况下,您可以在mutator方法中检查此类输入。这样可以避免在不同的地方手动检查和重复错误检查
另外建议您不要编写返回对可变对象的引用的访问器方法。这将破坏封装。使用对象类的.clone()
方法返回一个对象。