OOP,受保护与公共。什么时候使用?
我试图了解将类变量设置为私有与公共的好处。我理解 getters/setters 来访问/修改私有/受保护的数据,但它的唯一目的是“防止我破坏我的数据”吗?示例:我不明白“说”
$person->age = x;//bad?
与“说”具有不同的破坏潜力
$person->set_x(x);//reccommended in OOP articles
Im trying to understand the benefits of making a class variable private, versus public. I understand getters / setters to access / modify the private / protected data, but is its sole purpose is to 'keep me from mangling my data'? Example : I dont get how saying
$person->age = x;//bad?
has different potential for havoc than
$person->set_x(x);//reccommended in OOP articles
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
protected 关键字经常被误解,甚至可能被过度使用。简而言之,protected 成员是用于与子类通信的,而 public 成员是用于与子类通信的
与来电者沟通。
The protected keyword is often misunderstood, and perhaps, overused. In short, protected members are for communicating with subclasses, and public members are for
communicating with callers.
防止您破坏它,防止其他人破坏它,并表达非公共成员不属于其他人应该看到的内容的想法 - 从而实现 封装。
Keep you from mangling it, keep others from mangling it, and express the idea that non-public members are not part of what others should see -thus achieving Encapsulation.
嗯,我认为set/get方法可以帮助更好地保证属性,因为如果直接更改值可能会带来一些麻烦,例如对代码有害。我认为set/get提供了一种方法供用户调用而不是直接操作属性。
Well, I think the set/get method can help better gurantee the attributes, as if you directly change the value might cause some troubles, e.g. harmful to the code. I think the set/get provide a method for the user to call rather than directly operate on the attributs.
通过提供访问器(setter / getter 方法,或使用支持它们的语言(如 C#)中的属性),开发人员可以在类与其用户之间定义更稳定的契约。用户不是通过实际读取或写入内存位置来直接访问字段,而是被迫调用一个方法,该方法又可以封装任何必要的逻辑。
反过来,当修改类的内部设计时,其契约需要更改的频率就会降低。因此提高了代码的可维护性和稳定性。
请注意,性能不是问题,因为现代 JIT 编译器能够优化对简单 getter/setter 的调用,从而消除实际调用,并且代码相当于直接访问底层内存位置。
编辑:
此外,setter 和 getter 通常可能具有不同的可见性(公共/受保护/私有),从而提供对指定值的读/写操作进行更细粒度控制的额外好处。
因此,最佳实践是尽可能避免公共字段,并使用 setter / getter 方法或属性来代替。
By providing accessors (setter / getter methods, or by using properties in languages that support them, like C#) the developer can define a more-stable contract between the class and its users. Instead of accessing a field directly, by actually reading or writing a memory location, the user is forced to call a method, that in turn can encapsulate any logic necessary.
In turn when modifying the class'es internal design, its contract needs to be changed less frequently. Hence maintainability and stability of the code is improved.
Note that performance is not a concern, because modern JIT compilers are able to optimize calls to trivial getters / setters in a way that the actual call is eliminated and the code is equivalent to direct access to the underlying memory location.
Edit:
Also, setter and getter may usually have different visibility (public / protected / private) providing the added benefit of more-granular control to read / write operations over a specified value.
Hence the best practice is to avoid public fields wherever possible and use setter / getter methods or properties instead.
这都是关于封装的。
假设您使用
$person->age = x
。现在,它可以正常工作,假设您在 100 个地方都有这条线。后来发现您希望将age
限制为大于 0 的数字。通过直接访问成员变量,无法轻松强制执行该限制。但假设您最初在这 100 个位置编写了
$person->set_age(x)
。现在,您可以将 setter 从 更改为
您不必接触 set_age 方法的单个使用者;这些变化“有效”。这就是 OOP 的真正魅力:您可以在单个方法调用后面隐藏大量实现细节。
封装也可以在其他地方有所帮助:假设您想要一个 Person 的子类来记录每个年龄的变化。使用 setter 方法,就像重写一样简单;如果直接访问变量,那就会很混乱。
It's all about encapsulation.
Say you use
$person->age = x
. For now, it'll work fine, and let's say you have that line in 100 places. Later on it turns out that you want to restrictage
to, say, numbers greater than 0. With direct access to the member variable, there's no way to easily enforce that restriction.But let's say you'd originally written
$person->set_age(x)
in those 100 places. Now, you can change your setter fromto
You don't have to touch a single consumer of the set_age method; the changes "just work". That's the real beauty of OOP: you can hide a lot of implementation details behind a single method call.
The encapsulation can help elsewhere, too: say you wanted a subclass of Person that logged every age change. With the setter method, it's as easy as an override; with direct variable access, it would be a mess.