关于java:直接使用类属性

Working with class attributes directly

我听说直接使用类属性不是一个好主意,而是使用setter和getter。有人能告诉我为什么吗?


funnily足够的维基百科的文章在这个主题提供了良好的指导:http:///wiki/访问产生的

在短,应使用A级(mutator方法来验证制定的吸气,等)的输入,它是存储在私人。在这样做的,她总是ensures舱可以在选择的代码。

通过对比,如果有可用的属性是globably,可以修改它。如果你有一个字符串,例如,一个特定的格式,需要添加一个有价值的和不正确的,错误的可能结果。


在一个nutshell接口代码,如果你是一个私人包含吸气和制定出场)然后你可以互换的任何对象,conforms友好的界面。外部对象引用域均值,了解外部的外部用户。这直接耦合之间的消费对象和外部对象,这在本案例是一件坏事。

今天你的name场可能存储作为一String明年你可能不想更新它的一些更有趣的类型或从得到的信息在别的地方或东西……谁知道?使用一个现场可防止你这样做。使用访问器可以让你实现你想要的没有改变。这是更重要的比你可能认为的原则。

你可以找到这一接口:编码感兴趣吗?


事实上,Java不尊重统一访问原则。也就是说,用于更改字段值的客户机代码(如obj.field = newValue)与用于调用setter的代码(如obj.setField(newValue))非常不同。

如果您从一个公共字段开始,然后决定真正需要一个私有成员(例如,要添加验证或更改成员的基础实现),那么您的所有客户机代码都将中断。因此,如果您可能需要访问器提供的附加功能,则需要使用setter而不是公共字段。最终的结果是许多不必要的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Person {
   private String _firstName;
   private String _lastName;

   public Person(String firstName, String lastName) {
      _firstName = firstName;
      _lastName = lastName;
   }

   public String getFirstName() {
      return _firstName;
   }

   public void setFirstName(String name) {
      _firstName = name;
   }

   public String getLastName() {
      return _lastName;
   }

   public void setLastName(String name) {
      _lastName = name;
   }
}

在尊重UAP的语言中,例如scala,使用公共字段而不是getter/setter是很常见的。例如,scala中的上述类被写入:

1
2
3
4
5
class Person(var firstName: String, var lastName: String)

// example client code:
val p = new Person("John","Smith");
p.lastName ="Brown";

如果我决定需要验证,我可以将其替换为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Person(firstName: String, lastName: String)
   private var _firstName = validate(firstName);
   private var _lastName = validate(lastName);

   // getters
   def firstName: String = _firstName
   def lastName: String = _lastName

   // setters
   def firstName_=(name: String): Unit = {
      _firstName = validate(name);
   }

   def lastName_=(name: String): Unit = {
      _lastName = validate(name);
   }

   // validation
   @throws(classOf[IllegalArgumentException])
   private def validate(name: String): String = {
      // ... validation code ...
      name
   }
}

// and client code doesn't break!
val p = new Person("John","Smith");
p.lastName ="Brown";


有两个经典的原因你为什么要禁止外部访问域(属性)。论文介绍了面向对象的编程通常是类。

  • 如果基础数据是私有的,你是自由改变执行在类。例如,让我们说你的店数为一复杂的真实和虚部。然后,你决定你想改变,存储的Z和θ(大小和角度)。如果你暴露领域,没有任何变化的话,那它interacted班休息。如果你曾经使用accessors然后你可以实现getreal()和()getimaginary条件Z和θ都不休息。
  • 你可以添加其他运营到吸气和(特别是)制定的。例如,你可以保持跟踪的变化是如何在制造一场一场同步或更新它,但如果你只想改变任何这类试验场通过访问器去做它。你有没有一个公共场机会做这件事。

  • 这是一个会议,但一个强大的一个。

    它是由JavaBean规范的方法提供一个这样的事实,有没有Java的性能。

    它允许表示的意图(只读/写只读或读写属性。

    它是一个很好的手机连接在a a断点属性setter看到安切洛蒂unexplanedly为什么改变了。

    作为已经提到,但无法包含CAN接口accessors属性定义。

    有时你会想创建的虚拟属性,经典的例子是复杂的号码,你有X和Y属性和提供通孔和角计算模型在制定和吸气。

    许多API的依赖于这一类的意思infer会议通过的反射。

    现在所有的IDE自动生成的CAN他们所以他们不伤害我的手指在过去这么多。


    它只是一个简单的变化取决于;在class(布尔人),它会改变它时的感觉。如果它需要更复杂的(创建),那么你可能想实现和验证。

    大多数人把会员的私人数据集的方法,从而获得和使用这些数据必须来自外面的数据类。