java 您将如何从对象方法中访问对象属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How would you access Object properties from within an object method?
提问by cmcculloh
What is the "purist" or "correct" way to access an object's properties from within an object method that is not a getter/setter method?
从不是 getter/setter 方法的对象方法中访问对象属性的“纯粹”或“正确”方式是什么?
I know that from outside of the object you should use a getter/setter, but from within would you just do:
我知道从对象外部你应该使用 getter/setter,但从内部你会这样做:
Java:
爪哇:
String property = this.property;
PHP:
PHP:
$property = $this->property;
or would you do:
或者你会这样做:
Java:
爪哇:
String property = this.getProperty();
PHP:
PHP:
$property = $this->getProperty();
Forgive me if my Java is a little off, it's been a year since I programmed in Java...
如果我的 Java 有点不对,请原谅我,自从我用 Java 编程已经一年了......
EDIT:
编辑:
It seems people are assuming I am talking about private or protected variables/properties only. When I learned OO I was taught to use getters/setters for every single property even if it was public (and actually I was told never to make any variable/property public). So, I may be starting off from a false assumption from the get go. It appears that people answering this question are maybe saying that you should have public properties and that those don't need getters and setters, which goes against what I was taught, and what I was talking about, although maybe that needs to be discussed as well. That's probably a good topic for a different question though...
似乎人们假设我只是在谈论私有或受保护的变量/属性。当我学习 OO 时,我被教导对每个属性使用 getter/setter,即使它是公开的(实际上我被告知永远不要公开任何变量/属性)。所以,我可能从一开始就从一个错误的假设开始。似乎回答这个问题的人可能是说你应该有公共属性,那些不需要 getter 和 setter,这与我所学的和我所说的背道而驰,尽管也许这需要讨论为好。不过,对于另一个问题来说,这可能是一个很好的话题......
采纳答案by Greg Hurlman
This has religious war potential, but it seems to me that if you're using a getter/setter, you should use it internally as well - using both will lead to maintenance problems down the road (e.g. somebody adds code to a setter that needsto run every time that property is set, and the property is being set internally w/o that setter being called).
这具有宗教War的潜力,但在我看来,如果您正在使用 getter/setter,您也应该在内部使用它 - 使用两者将导致后期维护问题(例如,有人将代码添加到需要的 setter每次设置该属性时运行,并且该属性正在内部设置,而没有调用该设置器)。
回答by MojoFilter
Personally, I feel like it's important to remain consistent. If you have getters and setters, use them. The only time I would access a field directly is when the accessor has a lot of overhead. It may feel like you're bloating your code unnecessarily, but it can certainly save a whole lot of headache in the future. The classic example:
就我个人而言,我觉得保持一致很重要。如果您有 getter 和 setter,请使用它们。我直接访问字段的唯一时间是访问器有很多开销。你可能会觉得你不必要地膨胀了你的代码,但它肯定可以在未来省去很多麻烦。经典例子:
Later on, you may desire to change the way that field works. Maybe it should be calculated on-the-fly or maybe you would like to use a different type for the backing store. If you are accessing properties directly, a change like that can break an awful lot of code in one swell foop.
稍后,您可能希望更改该字段的工作方式。也许它应该即时计算,或者您可能想为后备存储使用不同的类型。如果您直接访问属性,那么像这样的更改可能会一次性破坏大量代码。
回答by moffdub
I'm fairly surprised at how unanimous the sentiment is that gettersand setters are fine and good. I suggest the incendiary article by Allen Holub "Getters And Setters Are Evil". Granted, the title is for shock value, but the author makes valid points.
我对这种情绪的一致感到相当惊讶,getters并且二传手很好。我推荐 Allen Holub 的煽动性文章“ Getter 和 Setter Are Evil”。当然,标题是为了震撼价值,但作者提出了有效的观点。
Essentially, if you have gettersand settersfor each and every private field, you are making those fields as good as public. You'd be very hard-pressed to change the type of a private field without ripple effects to every class that calls that getter.
从本质上讲,如果你有getters和setters对每一个私人领域,你正在这些领域不如众。您将很难更改私有字段的类型,而不会对调用该字段的每个类产生连锁反应getter。
Moreover, from a strictly OO point of view, objects should be responding to messages (methods) that correspond to their (hopefully) single responsibility. The vast majority of gettersand settersdon't make sense for their constituent objects;Pen.dispenseInkOnto(Surface)makes more sense to me than Pen.getColor().
此外,从严格的面向对象的角度来看,对象应该响应与其(希望)单一职责相对应的消息(方法)。绝大多数getters并且setters对它们的组成对象没有意义;Pen.dispenseInkOnto(Surface)对我来说比Pen.getColor().
Getters and setters also encourage users of the class to ask the object for some data, perform a calculation, and then set some other value in the object, better known as procedural programming. You'd be better served to simply tell the object to do what you were going to in the first place; also known as the Information Expertidiom.
getter 和 setter 还鼓励类的用户向对象询问一些数据,执行计算,然后在对象中设置一些其他值,这被称为过程编程。你最好先简单地告诉对象做你想做的事情;也称为信息专家习语。
Getters and setters, however, are necessary evils at the boundary of layers -- UI, persistence, and so forth. Restricted access to a class's internals, such as C++'s friend keyword, Java's package protected access, .NET's internal access, and the Friend Class Patterncan help you reduce the visibility of gettersand setters to only those who need them.
然而,getter 和 setter 是层边界上的必要之恶——UI、持久性等等。限制对类内部的访问,例如 C++ 的朋友关键字、Java 的包保护访问、.NET 的内部访问和Friend 类模式,可以帮助您将getters和 setter的可见性降低到仅需要它们的人。
回答by Shawn
It depends on how the property is used. For example, say you have a student object that has a name property. You could use your Get method to pull the name from the database, if it hasn't been retrieved already. This way you are reducing unnecessary calls to the database.
这取决于如何使用该属性。例如,假设您有一个具有 name 属性的 student 对象。如果尚未检索到名称,您可以使用 Get 方法从数据库中提取名称。通过这种方式,您可以减少对数据库的不必要调用。
Now let's say you have a private integer counter in your object that counts the number of times the name has been called. You may want to not use the Get method from inside the object because it would produce an invalid count.
现在假设您的对象中有一个私有整数计数器,用于计算名称被调用的次数。您可能不想在对象内部使用 Get 方法,因为它会产生无效计数。
回答by Unlabeled Meat
PHP offers a myriad of ways to handle this, including magic methods __getand __set, but I prefer explicit getters and setters. Here's why:
PHP 提供了无数种方法来处理这个问题,包括魔术方法__get和__set,但我更喜欢显式的 getter 和 setter。原因如下:
- Validation can be placed in setters (and getters for that matter)
- Intellisense works with explicit methods
- No question whether a property is read only, write only or read-write
- Retrieving virtual properties (ie, calculated values) looks the same as regular properties
- You can easily set an object property that is never actually defined anywhere, which then goes undocumented
- 验证可以放在 setter 中(以及与此相关的 getter)
- Intellisense 使用显式方法
- 毫无疑问,属性是只读、只写还是读写
- 检索虚拟属性(即计算值)看起来与常规属性相同
- 您可以轻松地设置从未在任何地方实际定义的对象属性,然后将其变为未记录的
回答by pix0r
Am I just going overboard here?
我只是在这里过火了吗?
Perhaps ;)
也许 ;)
Another approach would be to utilize a private/protected method to actually do the getting (caching/db/etc), and a public wrapper for it that increments the count:
另一种方法是使用私有/受保护的方法来实际进行获取(缓存/数据库/等),并使用一个公共包装器来增加计数:
PHP:
PHP:
public function getName() {
$this->incrementNameCalled();
return $this->_getName();
}
protected function _getName() {
return $this->name;
}
and then from within the object itself:
然后从对象本身内部:
PHP:
PHP:
$name = $this->_getName();
This way you can still use that first argument for something else (like sending a flag for whether or not to used cached data here perhaps).
通过这种方式,您仍然可以将第一个参数用于其他用途(例如发送一个标志是否在这里使用缓存数据)。
回答by Egg Vans
I must be missing the point here, why would you use a getter inside an object to access a property of that object?
我一定在这里错过了重点,为什么要在对象中使用 getter 来访问该对象的属性?
Taking this to its conclusion the getter should call a getter, which should call a getter.
以此得出结论,getter 应该调用 getter,getter 应该调用 getter。
So I'd say inside an object method access a property directly, especially seeing as calling another method in that object (which will just access the property directly anyway then return it) is just a pointless, wasteful exercise (or have I misunderstood the question).
所以我会说在一个对象方法中直接访问一个属性,特别是看到调用该对象中的另一个方法(无论如何它只会直接访问该属性然后返回它)只是一个毫无意义的浪费练习(或者我误解了这个问题)。
回答by Aadith Ramia
i would say its better to use the accessor methods even within the object. Here are the points that come to my mind immediately:
我会说即使在对象中使用访问器方法也更好。以下是我立即想到的要点:
1) It should be done in the interest of maintaining consistency with accesses made outside the object.
1) 这样做应该是为了保持与对象外部进行的访问的一致性。
2) In some cases, these accessor methods could be doing more than just accessing the field; they could be doing some additional processing (its rare though). If this is the case, by accessing the field directly you would missing out that additional processing and your program could go awry if this processing is always to be done during those accesses
2) 在某些情况下,这些访问器方法可能不仅仅是访问字段;他们可能会做一些额外的处理(虽然很少见)。如果是这种情况,通过直接访问该字段,您将错过额外的处理,如果在这些访问期间始终要进行此处理,您的程序可能会出错
回答by Martin Spamer
The purist OO way is to avoid both and follow the Law of Demeterby using the Tell Don't Askapproach.
纯粹的 OO 方法是通过使用“告诉不要问”方法来避免两者并遵循迪米特法则。
Instead of getting the value of the object's property, which tightly couplesthe two class, use the object as a parameter e.g.
不是获取对象属性的值,这将两个类紧密耦合,而是使用对象作为参数,例如
doSomethingWithProperty() {
doSomethingWith( this.property ) ;
}
Where the property was a native type, e.g. int, use an access method, name it for problem domain not the programming domain.
如果属性是本机类型,例如 int,则使用访问方法,将其命名为问题域而不是编程域。
doSomethingWithProperty( this.daysPerWeek() ) ;
These will allow you to maintain encapsulation and any post-conditions or dependent invariants. You can also use the setter method to maintain any pre-conditions or dependent invariants, however don't fall into the trap of naming them setters, go back to the Hollywood Principle for naming when using the idiom.
这些将允许您维护封装和任何后置条件或依赖不变量。您也可以使用 setter 方法来维护任何先决条件或依赖的不变量,但是不要陷入将它们命名为 setter 的陷阱,在使用习语时要回到好莱坞原则进行命名。
回答by Allain Lalonde
If by "purist" you mean "most encapsulation", then I typically declare all my fields as private and then use this.field from within the class itself, but all other classes, including subclasses, access instance state using the getters.
如果“纯粹主义者”是指“最封装”,那么我通常将所有字段声明为私有,然后在类本身中使用 this.field,但所有其他类(包括子类)使用 getter 访问实例状态。

