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

lnulla 发布于 2018-02-03 java 最后更新 2018-02-03 01:00 2348 浏览

什么是“纯粹”或“正确”的方式来访问对象的方法,而不是一个getter/setter方法的对象的属性? 我知道从对象的外面你应该使用一个getter/setter,但是从内部你会做: Java的:

String property = this.property;
PHP:
$property = $this->property;
或者你会做: Java的:
String property = this.getProperty();
PHP:
$property = $this->getProperty();
原谅我,如果我的Java有点关闭,这是一年以来,我用Java编程... 修改 看来人们正在假设我只谈论私有或受保护的变量/属性。当我学习OO时,我被教导使用getter/setter来处理每一个属性,即使这个属性是公开的(实际上我被告知从不公开任何变量/属性)。所以,我可能会从一个错误的假设开始。看来回答这个问题的人可能就是说你应该有公共财产,那些不需要得到的人,这与我所教导的和我所说的有所不同,尽管也许这需要讨论好。这可能是一个不同的问题,虽然好主题...
已邀请:

ehic

赞同来自:

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

nquae

赞同来自:

这取决于如何使用财产。例如,假设你有一个拥有name属性的学生对象。如果尚未检索到,则可以使用Get方法从数据库中提取名称。这样你就可以减少对数据库的不必要的调用。 现在让我们假设你的对象中有一个私有的整数计数器来计算名称被调用的次数。您可能不希望从对象内使用Get方法,因为它会产生无效的计数。

baut

赞同来自:

Am I just going overboard here?
也许 ;) 另一种方法是利用私有/受保护的方法来实际执行获取(缓存/数据库/等),并为其增加计数的公共包装: PHP:
public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}
protected function _getName() {
    return $this->name;
}
然后从对象本身: PHP:
$name = $this->_getName();
这样,你仍然可以使用第一个参数来做其他事情(比如发送一个标志来判断是否使用缓存数据)。

gipsam

赞同来自:

那么,似乎用C#3.0属性的默认实现,这个决定是为你而做的;你必须使用(可能是私有的)属性设置器来设置属性。 我个人只有在不这样做的时候才使用私有成员,这会导致对象处于一个不太理想的状态,比如初始化或者涉及到缓存/延迟加载时。

ut_sit

赞同来自:

正如一些评论所述:有时你应该,有时你不应该。关于私有变量的很大一部分是,当你改变某些东西的时候你可以看到所有的地方。如果你的getter/setter做了你需要的东西,就用它。如果没关系,你决定。 相反的情况是,如果你使用getter/setter,而有人改变了getter/setter,他们必须分析getter和setter在内部使用的所有地方,看看是否弄乱了某些东西。

zin

赞同来自:

就个人而言,我觉得保持一致是很重要的。如果你有吸气剂和吸附剂,使用它们。我唯一直接访问字段的时候是访问者有很多开销。这可能会让你觉得不必要地膨胀了你的代码,但是将来肯定可以节省很多的头痛。经典的例子: 稍后,您可能希望改变该领域的工作方式。也许它应该被即时计算,或者您可能想要使用不同类型的后备商店。如果你是直接访问属性,像这样的变化可以打破一个膨胀foop很多代码。

faut

赞同来自:

我可能是错误的,因为我autodidact,但我从来没有用户在我的爪哇公共属性,他们是总是私人或受保护的,所以外部代码必须访问getters/setters。维护/修改的目的更好。而对于内部类代码...如果getter方法是微不足道的,我直接使用属性,但我总是使用setter方法,因为如果我愿意,我可以很容易地添加代码来引发事件

nquis

赞同来自:

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

tfugit

赞同来自:

私人领域与公共或受保护的财产。对值的访问应该通过属性,如果在方法中多次使用它们,则将其复制到局部变量中。如果并且只有当你的应用程序的其余部分完全调整,摆脱了,否则就优化到哪里通过经历他们的协调属性访问价值已经成为一个瓶颈(我永远不会发生,我保证),如果你甚至开始考虑让属性以外的任何东西直接触及其支持变量。 .NET开发人员可以使用自动属性来执行此操作,因为在设计时您甚至无法看到支持变量。

uaut

赞同来自:

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

godio

赞同来自:

如果我不编辑属性,我将使用get_property()公共方法,除非它是另一个对象内部的特殊情况,例如MySQLi对象,在这种情况下,我将公开该属性并将其称为$obj->object_property。 在对象内部,对于我来说总是$ this-> property。

funde

赞同来自:

我喜欢cmcculloh的答案,但似乎最正确的是Greg Hurlman的答案。如果您从getgo开始使用getter/setter,并且/或者习惯于使用getter/setter,则始终使用getter/setter。 另外,我个人发现使用getter/setter可以使代码更容易阅读和稍后调试。

noptio

赞同来自:

我非常惊讶getters和setters是好的,感觉如何一致。我建议Allen Holub“Getters And Setters Are Evil”的燃烧篇。当然,标题是冲击价值,但作者提出了有效的观点。 从本质上讲,如果你有每个私人领域的getterssetters,那么你就是把这些领域做得和公共一样好。你很难将没有连锁反应的私人领域的类型改为每个调用getter的类。 此外,从严格的OO观点来看,对象应该回应与其(希望)单一责任相对应的消息(方法)。绝大多数getterssetters对于其组成对象都没有意义; Pen.dispenseInkOnto(Surface)Pen.getColor()更有意义。 吸气师和制定者也鼓励班级的用户向对象询问一些数据,进行计算,然后在对象中设置一些其他的值,也就是程序编程。你最好只是简单地告诉对象去做你将要做的事情。也被称为Information Expert成语。 然而,吸气者和制定者是图层边界的必要罪恶 - UI,持久性等等。对C++的friend关键字,Java的包保护访问,.NET的内部访问和Friend Class Pattern等类的内部访问的限制可以帮助您将getters和setter的可见性减少到只有需要它们的人。

vet

赞同来自:

纯粹的OO方法是避免两者,并使用Tell Don't Ask方法跟随Law of Demeter。 这个tightly couples这两个类不是获取对象属性的值,而是使用该对象作为参数,例如

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }
在属性是本地类型的情况下,例如int,使用访问方法,将其命名为问题域而不是编程域。
  doSomethingWithProperty( this.daysPerWeek() ) ;
这些将允许您保持封装和任何后置条件或从属的不变量。你也可以使用setter方法来维护任何前置条件或依赖不变式,但是不要陷入为setters命名的陷阱,在使用成语时要回到好莱坞原则来命名。

lquia

赞同来自:

PHP提供了无数的方法来处理这个问题,包括神奇的方法getset,但是我更喜欢显式的getter和setter。原因如下:

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

tut

赞同来自:

这取决于。这是一个风格问题,而不是其他任何事情,没有硬性规定。

yquo

赞同来自:

我会说它更好地使用访问器方法,即使在对象内。以下是我立即想到的几点: 1)为了保持与对象之外访问的一致性,应该这样做。 2)在某些情况下,这些访问方法可能不仅仅是访问该领域;他们可以做一些额外的处理(尽管罕见)。如果是这种情况,通过直接访问该字段,您将错过额外的处理,并且如果在这些访问期间总是要执行处理,则程序可能会出错

jculpa

赞同来自:

我必须在这里忽略这一点,为什么你会在对象内部使用一个getter来访问该对象的属性? 得出这个结论后,吸气者应该调用一个吸气剂,它应该叫做吸气剂。 所以我会说在一个对象方法内直接访问一个属性,尤其是看到调用该对象中的另一个方法(它将直接访问该属性直接返回它)只是一个毫无意义,浪费的练习(或者我误解了这个问题)。