你将如何访问对象方法中的对象属性?

从不是getter / setter方法的对象方法中访问对象属性的“纯粹”或“正确”方式是什么?

我知道从对象外部你应该使用getter / setter,但从内部你会做:

Java的:

String property = this.property;

PHP:

$property = $this->property;

或者你会这样做:

Java的:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

请原谅我,如果我的Java有点不合适,那是因为我用Java编程了一年。

修改</强>

似乎人们认为我只是在讨论私有或受保护的变量/属性。当我学会了面向对象的时候,我被教导使用getter / setter来处理每一个属性,即使它是公开的(实际上我被告知从不公开任何变量/属性)。所以,我可能会从一个错误的假设开始。看来回答这个问题的人可能会说你应该拥有公共财产,并且那些不需要获得者和制定者,这违背了我所教的内容以及我正在谈论的内容,尽管也许这需要讨论好。这可能是一个不同问题的好主题,但......

0
额外 编辑
意见: 1

17 答案

这取决于如何使用该财产。例如,假设您有一个拥有名称属性的学生对象。如果尚未检索到,则可以使用Get方法从数据库中提取名称。这样你就可以减少对数据库的不必要的调用。

现在假设您的对象中有一个私有整数计数器,用于计算名称被调用的次数。您可能不想使用对象内部的Get方法,因为它会产生无效的计数。

0
额外
如果你添加某种类型的布尔值给getter,如下所示:PHP:public function getName($ outsideCall = true){if($ outsideCall){$ this-> incrementNameCalled(); } return $ this-> name; }然后从Object内部,如果你调用了get name,你可以通过下面的方法防止它增加:PHP:$ name = $ this-> getName(false);我只是在这里过度?
额外 作者 cmcculloh,
如果Student对象是业务/域对象,则您现在正在混合基础架构详细信息。理想情况下,业务/域对象应该只关注业务/域逻辑。
额外 作者 moffdub,
我只是在这里过度了吗?

也许 ;)

另一种方法是利用私有/受保护的方法来实际执行获取(缓存/ db / etc)以及用于增加计数的公共包装器:

PHP:

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

然后从对象内部:

PHP:

$name = $this->_getName();

这样,你仍然可以使用第一个参数来做其他事情(比如发送一个标志来判断是否在这里使用缓存数据)。

0
额外

就我个人而言,我觉得保持一致是很重要的。如果你有getters和setters,使用它们。我直接访问字段的唯一时间是访问者有很多开销。它可能会让你觉得不必要地膨胀你的代码,但它可以在将来避免很多头痛。经典例子:

稍后,您可能希望改变该领域的工作方式。也许它应该被即时计算,或者您可能想要为后备商店使用不同的类型。如果你直接访问属性,像这样的变化可以在一个浮动foop中打破很多代码。

0
额外

这具有宗教战争的潜力,但在我看来,如果你使用getter / setter,你也应该在内部使用它 - 使用这两者都会导致维护问题(例如有人向代码中添加代码, em> needs 在每次设置该属性时运行,并且该属性在内部设置,而不是在调用该设置器时设置)。

0
额外
也许吧,但这并不妨碍它的发生。
额外 作者 Greg Hurlman,
除了将属性的值设置为Java中错误用法的示例之外,没有在setter中做任何其他操作。
额外 作者 euphoria83,

那么,它似乎与C#3.0属性的默认实现,这是你的决定;你必须使用(可能是私有的)属性设置器来设置属性。

我个人仅在不这样做时使用私有成员会导致对象处于不太理想的状态,比如初始化或涉及缓存/延迟加载时。

0
额外

正如一些评论所述:有时你应该,有时你不应该。关于私有变量的很大一部分是,当你改变某些东西时,你可以看到它们被使用的所有地方。如果你的getter / setter做了你需要的东西,就用它。如果你决定无关紧要。

相反的情况是,如果你使用getter / setter并且有人更改getter / setter,他们必须分析getter和setter在内部使用的所有地方,以查看它是否会引起混乱。

0
额外

我可能是错误的,因为我是autodidact,但我永远不会在我的Java类中使用公共属性,它们始终是私有的或受保护的,因此外部代码必须由getters / setter访问。这对维护/修改目的更好。而对于内部类代码...如果getter方法是微不足道的,我直接使用属性,但我总是使用setter方法,因为如果我愿意,我可以轻松添加代码来引发事件。

0
额外

如果通过“纯粹”你的意思是“最封装”,那么我通常将我所有的字段声明为私有,然后在类本身内使用this.field,但所有其他类(包括子类)使用getter访问实例状态。

0
额外

这取决于。这不仅仅是一个风格问题,也没有硬性规定。

0
额外

If I won't edit the property I'll use a get_property() public method unless it's a special occasion such as a MySQLi object inside another object in which case I'll just public the property and refer to it as $obj->object_property.

Inside the object it's always $this->property for me.

0
额外

我会说它更好地使用访问器方法,即使在对象内。以下是我立即想到的几点:

1)为了保持与对象之外访问的一致性,应该这样做。

2)在某些情况下,这些访问方法可能不仅仅是访问该领域;他们可能会做一些额外的处理(尽管它很少见)。如果是这种情况,通过直接访问该字段,您将错过额外的处理,并且如果在访问期间总是要执行此处理,则您的程序可能会出错

0
额外

我非常惊讶于 getters 和setter是好的,情绪如何一致。我建议艾伦霍勒布的燃烧文章“吸气者和安慰者是邪恶”。诚然,标题是为了震撼价值,但作者提出了有效的观点。

从本质上讲,如果你对每个私人领域都有 getterssetters ,那么你可以使这些领域与公共领域一样好。你很难将没有涟漪效应的专用字段类型更改为每个调用 getter 的类。

此外,从严格的OO观点来看,对象应该回应与他们(希望)单一责任相对应的消息(方法)。绝大多数 getterssetters 对于它们的组成对象都没有意义; Pen.dispenseInkOnto(Surface)比我更有意义, <�代码> Pen.getColor()</代码>。

吸气师和制定者也鼓励班级的使用者向对象询问一些数据,进行计算,然后在对象中设置一些其他的值,这就是程序编程。你最好只是简单地告诉对象先做你要做的事;也被称为信息专家成语。

然而,吸气者和制定者是图层边界的必要罪恶 - UI,持久性等等。限制对类内部的访问,比如C ++的friend关键字,Java的包保护访问,.NET的内部访问以及 Friend Class Pattern 可以帮助您将 getters 和setter的可见性减少到只有需要它们的人。

0
额外

我发现使用setter / getters让我的代码更易于阅读。我还喜欢其他类使用方法时所给予的控制权,如果我更改了属性将存储的数据。

0
额外

私人领域与公共或受保护的财产。对值的访问应该通过属性,并且如果它们将在方法中多次使用,则将其复制到局部变量。如果并且只有当你的应用程序的其他部分完全调整好后,才能进行优化,否则就应该优化到哪里通过经历他们的分散属性来访问价值已成为瓶颈(而且我绝对不会发生这种情况,我保证)你应该甚至开始考虑让属性以外的任何东西直接触及其支持变量。

.NET开发人员可以使用自动属性来强制执行此操作,因为在设计时您甚至无法看到支持变量。

0
额外

PHP提供了许多方法来处理这个问题,包括魔术方法 __ get__ set ,但我更喜欢显式的getter和setter。原因如下:

  1. 验证可以放置在setter(和getters)中
  2. Intellisense使用显式方法
  3. 毫无疑问,属性是只读的,只写还是读写
  4. 检索虚拟属性(即计算值)看起来与常规属性
  5. 相同
  6. 您可以轻松设置一个永远不会在任何地方实际定义的对象属性,然后该对象属性会被记录为
0
额外

我必须在这里忽略这一点,为什么你会在对象中使用getter来访问该对象的属性?

以此为结论,吸气人员应调用一个吸气器,它应该称为吸气剂。

所以我会说在一个对象方法中直接访问一个属性,尤其是看到调用另一个方法(直接访问属性然后返回它)只是一个毫无意义,浪费的练习(或者我误解了这个问题)。

0
额外
我被同样的需求所驱使,你必须评论......另外,它的答案并未关闭;)
额外 作者 Egg Vans,