【问题标题】:Class attribute declaration: private vs public类属性声明:private vs public
【发布时间】:2010-10-17 06:21:00
【问题描述】:

定义私有属性而不是公共属性有什么好处?如果我可以公开私有属性,为什么还要创建访问和修改私有属性的方法?

【问题讨论】:

    标签: oop class attributes


    【解决方案1】:

    在短期内没有,除了让 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..
      ...
    }
    

    【讨论】:

      【解决方案2】:

      如果您使用 getter/setter,您可以在更改或访问时执行逻辑。您可以验证输入,而不是假设它总是正确的。您可以跟踪获取该值的次数。

      最重要的是,这是一个很好的设计。它使您(该类的开发人员)能够更好地控制它的使用方式,并更好地防止误用、滥用或只是某人做错事。

      【讨论】:

        【解决方案3】:

        主要是因为封装的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;
           }
        }
        

        当然这是一个简单的例子。然而,这表明控制对类字段/属性的访问是多么重要。 想象一个具有更复杂状态控制的更复杂对象。封装使得对象的抽象性和一致性更好。

        【讨论】:

        • 是的,但是你的一个班级最后一次流氓并开始从其他物体上偷钱是什么时候?
        • 以后代码比较大,有人想用代码的时候,可能有人看到numberOfCoins属性是公开的,直接改就可以得到结果了。但是当他们调用 haveMoney 函数并期望它是准确的时,他们可能会得到一个不正确的结果。
        【解决方案4】:

        因为您应该始终努力从接口保护实现。如果您公开某个属性,您就是在让客户知道您对该属性的实现情况。

        这不仅使您保持接口,而且还保持实现。

        此外,如果您使用方法,您还可以执行其他智能操作,例如验证、访问控制、记帐。如果您将某个属性设为公开,那么您对客户端可以使用该属性执行的操作的控制权就会大大减少

        【讨论】:

          【解决方案5】:

          如果您创建访问方法,则将实现与接口分开。

          【讨论】:

          • ...为什么这是可取的?
          • @Rob 然后实现可以完全改变,任何使用该接口的代码都不必知道它。
          【解决方案6】:

          私有属性为您提供了一个级别的保护,以防止您的类用户针对该属性。如果您使用公共属性,则需要添加更多逻辑来预先测试无效值,这可能需要更多的工作,并且计算成本更高。

          公共属性也会“混乱”界面。您提供的公共属性越少,您的对象就越“干净”和更容易使用。将某些属性设为私有可以为您提供灵活性,同时提供其他情况下无法使用的易用性。

          【讨论】:

            【解决方案7】:

            在 C# 中它是惯用的。这意味着公共字段会令人惊讶,并使其他人需要更长的时间才能理解您的代码。

            它是惯用的原因与人们给出的其他解释有关,但它是惯用的事实意味着您应该更喜欢属性而不是公共字段,除非有令人信服的理由使用字段。

            【讨论】:

              【解决方案8】:

              通常,只有在您认为有必要时,您才会对要在程序逻辑中隔离的字段使用 Private 声明。

              公共声明让您可以更好地控制自己的程序流程;您可以随时更改公共字段。你是家里的男人。

              那么,为什么大多数人会自发地对 Private 声明做出“BIG YES”的回应?

              因为:

              • 在大学里,他们被教导“就那样”去做。 (最谨慎的理由)
              • 他们最终愚蠢地立即假设您正在构建代码库,构建软件组件供他人使用,或者正在从事某些密码学实施。只有在这些情况下,您才会不确定您的字段会发生什么。

              底线是惊人的“商业”!如果你是在“卖”它,那就去私有化,否则做你喜欢的事。

              【讨论】:

                【解决方案9】:

                如果所有属性都是私有的,那么从长远来看你会更好。这包括不使用吸气剂。如果您正在访问对象的属性,那么您正在破坏封装,并且根本没有真正进行 OOP。到那时,构建类的大部分理由都被浪费了。为什么要建造一座城堡来抵御入侵者,然后让所有的门都敞开?或者(与吸气剂)总是根据要求欢迎入侵者。

                “得墨忒耳法则”和“告诉不要问”的方法已被证明可以降低生产代码中的错误率。使用公共属性不会让面向对象的纯粹主义者不高兴,它只会使用您的代码阻止他们。

                告诉你的对象如何处理它们的属性,不要向它们询问值,操作它们并将它们写回。这就像带一只狗去散步,然后一根一根地捡起它的腿让它动起来。

                顺便说一句,相反,行为都应该是公开的。任何看起来应该是私有的方法实际上是另一个类的未提取方法。提取该类和方法,然后亲眼目睹您的设计简化。

                【讨论】:

                  猜你喜欢
                  • 2020-07-31
                  • 2011-04-02
                  • 2021-06-11
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-01-19
                  • 1970-01-01
                  相关资源
                  最近更新 更多