【发布时间】:2010-10-17 06:21:00
【问题描述】:
定义私有属性而不是公共属性有什么好处?如果我可以公开私有属性,为什么还要创建访问和修改私有属性的方法?
【问题讨论】:
标签: oop class attributes
定义私有属性而不是公共属性有什么好处?如果我可以公开私有属性,为什么还要创建访问和修改私有属性的方法?
【问题讨论】:
标签: oop class attributes
在短期内没有,除了让 OOP 纯粹主义者不开心。
(我假设您的意思是公开原本会使用 getter/setter 的属性 - 如果您将所有属性都公开,显然会有很大的不同)。
从长远来看,这样做有几个非常好的理由。
首先,它允许您在输入源处验证输入,而不必稍后通过硬件断点和黑魔法的组合回溯原点。
例如
void Foo::setWeight(float weight)
{
ASSERTMSG(weight >= 0.0f && weight <= 1.0f, "Weights must fall in [0..1]");
mWeight = weight;
}
它还允许您稍后更改对象的行为,而无需重构客户端代码。
例如
void Foo::setSomething(float thing)
{
mThing = thing;
// 2009/4/2: turns out we need to recalc a few things when this changes..
...
}
【讨论】:
如果您使用 getter/setter,您可以在更改或访问时执行逻辑。您可以验证输入,而不是假设它总是正确的。您可以跟踪获取该值的次数。
最重要的是,这是一个很好的设计。它使您(该类的开发人员)能够更好地控制它的使用方式,并更好地防止误用、滥用或只是某人做错事。
【讨论】:
主要是因为封装的OO概念。使用 private 可以封装对对象变量的访问,从而保持对对象状态的控制。不允许外部对象更改您不知道的对象的状态。
一个简单的例子是一个 Pocket 对象。
class Pocket {
public int numberOfCoins = 10;
private boolean haveMoney = true;
public void giveOneCoin(){
if(stillHaveMoney()){
numberOfCoins--;
if(numberOfCoins=<0){
haveMoney=false;
}
}
}
public boolean stillHaveMoney(){
return haveMoney;
}
}
现在想象另一个类如下:
class PickPockets {
public void getSomeMoney(Pocket pocket){
pocket.numberOfCoins=0;
}
}
当然这是一个简单的例子。然而,这表明控制对类字段/属性的访问是多么重要。 想象一个具有更复杂状态控制的更复杂对象。封装使得对象的抽象性和一致性更好。
【讨论】:
因为您应该始终努力从接口保护实现。如果您公开某个属性,您就是在让客户知道您对该属性的实现情况。
这不仅使您保持接口,而且还保持实现。
此外,如果您使用方法,您还可以执行其他智能操作,例如验证、访问控制、记帐。如果您将某个属性设为公开,那么您对客户端可以使用该属性执行的操作的控制权就会大大减少
【讨论】:
如果您创建访问方法,则将实现与接口分开。
【讨论】:
私有属性为您提供了一个级别的保护,以防止您的类用户针对该属性。如果您使用公共属性,则需要添加更多逻辑来预先测试无效值,这可能需要更多的工作,并且计算成本更高。
公共属性也会“混乱”界面。您提供的公共属性越少,您的对象就越“干净”和更容易使用。将某些属性设为私有可以为您提供灵活性,同时提供其他情况下无法使用的易用性。
【讨论】:
在 C# 中它是惯用的。这意味着公共字段会令人惊讶,并使其他人需要更长的时间才能理解您的代码。
它是惯用的原因与人们给出的其他解释有关,但它是惯用的事实意味着您应该更喜欢属性而不是公共字段,除非有令人信服的理由使用字段。
【讨论】:
通常,只有在您认为有必要时,您才会对要在程序逻辑中隔离的字段使用 Private 声明。
公共声明让您可以更好地控制自己的程序流程;您可以随时更改公共字段。你是家里的男人。
那么,为什么大多数人会自发地对 Private 声明做出“BIG YES”的回应?
因为:
底线是惊人的“商业”!如果你是在“卖”它,那就去私有化,否则做你喜欢的事。
【讨论】:
如果所有属性都是私有的,那么从长远来看你会更好。这包括不使用吸气剂。如果您正在访问对象的属性,那么您正在破坏封装,并且根本没有真正进行 OOP。到那时,构建类的大部分理由都被浪费了。为什么要建造一座城堡来抵御入侵者,然后让所有的门都敞开?或者(与吸气剂)总是根据要求欢迎入侵者。
“得墨忒耳法则”和“告诉不要问”的方法已被证明可以降低生产代码中的错误率。使用公共属性不会让面向对象的纯粹主义者不高兴,它只会使用您的代码阻止他们。
告诉你的对象如何处理它们的属性,不要向它们询问值,操作它们并将它们写回。这就像带一只狗去散步,然后一根一根地捡起它的腿让它动起来。
顺便说一句,相反,行为都应该是公开的。任何看起来应该是私有的方法实际上是另一个类的未提取方法。提取该类和方法,然后亲眼目睹您的设计简化。
【讨论】: