java -如何从对象方法中访问对象属性?

Translate

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

我知道从对象外部您应该使用getter / setter,但是从内部您只需要这样做:

Java:

String property = this.property;

PHP:

$property = $this->property;

还是你会做:

Java:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

原谅我,如果我的Java有点过时了,距离我用Java编程已经一年了...

编辑:

似乎人们以为我只是在谈论私有或受保护的变量/属性。当我学习面向对象时,我被教导即使每个属性都是公共的,也要对每个属性都使用吸气剂/设置器(实际上,我被告知永远不要公开任何变量/属性)。因此,我可能一开始就从一个错误的假设开始。似乎回答这个问题的人可能是在说您应该拥有公共财产,而那些人不需要吸气剂和塞子,这与我所教的内容和我所谈论的内容背道而驰,尽管可能需要将其讨论为好。不过,这可能是另一个问题的好话题...

This question and all comments follow the "Attribution Required."

所有的回答

Translate

这具有宗教上的战争潜力,但是在我看来,如果您使用的是吸气剂/塞特剂,则也应该在内部使用它-两者同时使用会导致维护问题(例如,有人向设置员添加代码,需要会在每次设置该属性时运行,并且在内部设置该属性而无需调用该setter)。

来源
Translate

就个人而言,我觉得保持一致很重要。如果您有getter和setter,请使用它们。我唯一直接访问字段的时间是访问器有很多开销。看起来您好像不必要地膨胀了代码,但将来肯定可以省去很多麻烦。经典示例:

稍后,您可能希望更改该字段的工作方式。也许应该即时计算,或者您想为后备商店使用其他类型。如果您直接访问属性,则这样的更改可能会使大量代码中断。

来源
Translate

我对这种情感有多么一致感到惊讶getters和二传手都很好。我建议艾伦·霍鲁布(Allen Holub)的煽动性文章“吸气剂和二传手是邪恶的“。的确,标题是震撼价值,但作者提出了有效的观点。

本质上,如果您有getterssetters对于每个私人领域,您都将这些领域变得与公共领域一样好。您很难改变私有字段的类型,而不会给调用它的每个类带来连锁反应getter.

而且,从严格的面向对象的角度来看,对象应该响应与其(希望)单一职责相对应的消息(方法)。绝大多数getterssetters对于它们的构成对象没有任何意义;Pen.dispenseInkOnto(Surface)对我来说比Pen.getColor().

Getter和Setter还鼓励该类的用户向对象询问一些数据,执行计算,然后在该对象中设置其他值,这被称为过程编程。最好只是简单地告诉对象要做您打算做的事情。也称为信息专家成语。

但是,getter和setter是在层边界(UI,持久性等)上必不可少的弊端。限制对类内部的访问,例如C ++的friend关键字,Java的程序包保护的访问,.NET的内部访问以及朋友班模式可以帮助您降低可见度getters并只针对需要他们的人。

来源
Translate

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

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

来源
Translate

PHP提供了多种方法来解决此问题,包括魔术方法__get__set,但我更喜欢显式的getter和setter方法。原因如下:

  1. 可以将验证放置在setter(以及与此相关的getter)中
  2. Intellisense使用显式方法
  3. 毫无疑问,属性是只读,只写还是读写
  4. 检索虚拟属性(即计算值)看起来与常规属性相同
  5. 您可以轻松设置一个从未在任何地方实际定义的对象属性,然后将其记录下来
来源
Translate

我只是在这里落水吗?

也许 ;)

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

PHP:

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

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

然后从对象本身内部:

PHP:

$name = $this->_getName();

这样,您仍然可以将第一个参数用于其他内容(例如,发送标志以了解此处是否使用了缓存的数据)。

来源
Translate

我必须在这里遗漏一点,为什么要在对象内使用吸气剂来访问该对象的属性?

得出结论,吸气剂应称为吸气剂,吸气剂应称为吸气剂。

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

来源
Translate

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

来源
Translate

我想说最好甚至在对象内使用访问器方法。我立即想到以下几点:

1)这样做的目的是保持与对象外部访问的一致性。

2)在某些情况下,这些访问器方法可能做的不仅仅是访问字段。他们可能会做一些额外的处理(虽然很少见)。如果是这种情况,那么直接访问该字段将导致您错过额外的处理,并且如果在这些访问期间始终必须执行此处理,则程序可能会出错

来源
Translate

纯粹的OO方法是避免两者并遵循得墨meter耳定律通过使用告诉不要问方法。

与其获取对象属性的值,不如情侣这两个类,使用对象作为参数,例如

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

如果属性是本机类型,例如int,则使用访问方法,将其命名为问题域而不是编程域。

  doSomethingWithProperty( this.daysPerWeek() ) ;

这些将使您能够维护封装以及任何后置条件或因变量。您也可以使用setter方法来维护任何前提条件或相关不变量,但是不要陷入为它们指定命名器的陷阱,使用成语时请回到Hollywood原理进行命名。

来源
Translate

我发现使用setters / getters使我的代码更易于阅读。我也喜欢其他类使用方法时提供的控件,如果我更改属性将存储的数据。

来源
Mel
Translate

具有公共或受保护属性的私有字段。对值的访问应通过属性,如果在方法中将多次使用它们,则应将其复制到局部变量。如果并且仅当您对应用程序的其余部分进行了完全调整,精简以及以其他方式进行了优化,以至于通过遍历它们的关联属性访问值已成为瓶颈(而且这永远不会发生,我保证)永远都应该开始考虑让属性以外的任何内容直接接触其后备变量。

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

来源
Translate

如果我不编辑媒体资源,我将使用get_property()public方法,除非是特殊情况,例如另一个对象内的MySQLi对象,在这种情况下,我将公开该属性并将其称为$obj->object_property.

在对象内部,对我来说,始终是$ this-> property。

来源
Translate

这取决于。这比其他任何事情都更是样式问题,没有硬性规定。

来源
Translate

我可能是错误的,因为我是自动编辑的,但是我从不在Java类中使用公共属性,它们始终是私有的或受保护的,因此外部代码必须由getter / setter进行访问。更好地用于维护/修改目的。对于内部类代码...如果getter方法很简单,我将直接使用该属性,但是我始终使用setter方法,因为如果愿意,我可以轻松地添加代码以引发事件。

来源
Translate

好吧,似乎有了C#3.0属性的默认实现,该决定就由您决定;您必须使用(可能是私有的)属性设置器来设置属性。

我个人仅在不使用私有成员的情况下使用,否则会导致对象处于不理想的状态,例如在初始化时或在涉及缓存/延迟加载时。

来源
Dolores Lee
Translate

我喜欢答案cmcculloh,但似乎最正确的答案是格雷格·霍尔曼(Greg Hurlman)。如果您从getgo开始使用getter / setter和/或习惯使用它们,请始终使用getter / setter。

顺便说一句,我个人发现使用getter / setters可以使代码更易于阅读和以后进行调试。

来源
Translate

正如一些评论中所述:有时应该,有时不应该。关于私有变量的重要之处在于,您可以在更改某些内容时看到它们被使用的所有位置。如果您的getter / setter执行了您需要的操作,请使用它。如果没关系,您可以决定。

可能出现相反的情况,如果您使用吸气剂/设置器并且有人更改了吸气剂/设置器,他们必须分析内部使用吸气剂和设置器的所有位置,以查看是否弄乱了某些东西。

来源