【问题标题】:Use of getter-setter within class在类中使用 getter-setter
【发布时间】:2011-06-13 15:11:43
【问题描述】:

在任何情况下都应该在类中使用类的getter-setter吗?

【问题讨论】:

    标签: oop class getter-setter


    【解决方案1】:

    getter setter 通常用于从外部类从内部直接访问字段。 主要优点/目的是 封装 getter setter,

    如果您的 getter setter 有一些逻辑代码,请使用它。

    例如:

    public void setValue(int val){
      if(val > 100)
        this.val = 0;
      else
        this.val = val;
      }
    

    另见

    【讨论】:

    • @Geolez 我没有看到 OP 的 PHP 标签,这里描述的 OOP 概念并不特定于任何语言
    【解决方案2】:

    是的,getter 和 setter 很有用。因为 PHP 不支持像 int 或 string 这样的简单类型的类型提示,所以不能强制一个值是正确的类型。

    通过使用设置器,您始终可以检查设置的值。当设置为 int 属性的值不是 int 时,您可以选择对其进行类型转换或引发错误,而不仅仅是接受错误的值。

    这将使调试和维护您的应用程序变得更加容易。因此使用 getter 和 setter 是个好主意,即使它们除了这些检查之外不包含太多逻辑。

    【讨论】:

    • +1。这很有用,谢谢,org.life 是对的。我故意没有添加特定语言的标签
    【解决方案3】:

    您应该几乎在任何地方都使用 getter 和 setter,包括在类内部。如果你不这样做,那么你可能会破坏封装,更糟糕的是,你可能会使你的不变量无效。

    作为一个简单的 C++ 示例:

    class BankAccount
    {
    public:
        void withdraw(int amount)
        {
            m_balance -= amount;
            m_withdrawals++;
        }
    
        void transfer(BankAcount& other, int amount)
        {
            m_balance -= amount;
            other.m_balance += amount;
        }
    
    private:
        int m_balance;
        int m_withdrawals;
    };
    

    看到错误了吗? transfer 提款,但不会增加 m_withdrawals。如果它只是调用withdraw 而不是手动减少余额,则可以避免这种情况。

    这同样适用于 getter 和 setter。例如,让 getter 懒惰地初始化它们的值是很常见的。如果另一个成员函数尝试直接访问未初始化的成员,那么您将获得一个空指针取消引用。

    基本上,只要 getter 和 setter 提供所需的功能,您就应该始终尝试使用它们。你做的低级的事情越多,你就会有越多的低级错误。如果您不打算使用 getter 和 setter,那么编写它们是没有意义的。

    【讨论】:

    • 我认为您描述的示例不是针对 getter/setter,而是针对封装
    • Getter 和 setter 封装——这就是它们的全部目的。
    • "getter 和 setter 是封装" no :) getter 和 setter 打破了封装。封装 == 对象不会将其数据(属性)提供给外部。
    • @smentek:您将封装与单独监禁混淆了:)
    • 没有。请阅读 Allen 的 Holub:“通过查看代码学习设计模式”
    【解决方案4】:

    @GolezTrol

    主题上没有 PHP 徽章,你错了。您所描述的与二传手无关。您可以使用任何方法(不仅是 setter)强制参数类型(在 PHP 中)。

    你可以写:

    setX( X $x ){ ...}
    setY( Y $y ){ ...}
    

    或者只是:

      iAmMethodNotASetter( X $x, Y $y){
    
        //20lines of code here end then:
    
        $this->x = $x;
        $this->y = $y;
      }
    

    如您所见,我不需要 setter 来强制输入对象属性。

    在检查变量类型后在 setter 中抛出错误无论如何都是个坏主意。这是从静态类型语言过渡到动态类型语言的程序员的常见错误。

    Setter 和 geter 是 CONVENTION,它们不强制执行任何操作! 今天我们通常使用它们来创建普通的旧 Java 对象。 (POJO - 在 php 单词 POPO 中)所以它只是一个用于创建可以在库或项目之间使用的对象的约定(标准)。

    您可以将 setter 与类型检查或其他任何东西结合起来,但这并不会使它们变得比它们本身更重要。

    关于封装:

    @org.life.java - Jigar Joshi

    “主要优点/目的是 getter setter 的封装,"

    @彼得亚历山大

    “你应该使用吸气剂 几乎无处不在, 包括里面的“类。如果你 不要,那么你有可能 打破封装” “吸气剂和 setter 是封装”

    错了,错了,错了封装与 getter 和 setter 无关,这是很常见的错误。我知道有很多文章一遍又一遍地颠倒重复...
    更糟糕的是,getter 和 setter 无助于封装,它们可能会破坏封装。当您使用它们从对象获取一些数据而不是要求对象使用自己的数据为您做某事时,它们会这样做。

    Encapsulation == 对象对其数据承担全部责任,并且不提供其行数据。私有财产的吸气剂只不过是以复杂的方式公开该财产==制动封装。

    检查段落封装:http://en.wikipedia.org/wiki/C%2B%2Bhttp://en.wikipedia.org/wiki/Encapsulation_%28computer_science%29 甚至没有一个关于 setter 或 getter 的词......

    【讨论】:

    • 来自 wiki:“[封装是] 一种语言结构,有助于将数据与操作该数据的方法(或其他功能)捆绑在一起。” Getter 和 setter 是绑定到类中以对其数据进行操作的方法。无论如何,我给了你一个-1,因为你没有回答这个问题,你发帖只是为了骚扰其他回答者。为此使用 cmets。
    • +1。虽然你有点急躁,但你提出了一个有趣的观点。我必须多读一点。谢谢
    • 我没有错,错,错,只是我的回答可能对 PHP 来说太具体了。你错了,因为你不能通过使用类型提示来强制任何类型。您的“X”提示仅适用于类和数组,并且在数组的情况下,仍然没有提示 in 数组中应该包含什么。当然,您也可以使用其他方法执行此操作,但是因为您需要确定类型检查代码,所以您应该始终创建一个 setter并且始终使用该 setter,即使在该类中的方法中也是如此。但这是针对 PHP 的,大多数其他语言都是强类型的,不需要进行额外检查。
    • 当然,通过 setter 暴露另一个对象的私有对象不是一个好主意,但是当涉及到更简单的类型时,这应该不是问题。我可以通过 C++ 中的 setter 公开一个 int。通过使 setter 虚拟化,我可以决定让后代类实现一个不同的 setter,它甚至不设置私有变量。现在,确定你不应该为你不想从外部设置的东西创建公共设置器,但在很多情况下它是有道理的。 ...
    • ... 如果我有一个 Person 对象,我想通过 setAge 方法或 Age 属性设置他的年龄。在这种情况下,setAge 是二传手吗?如果你愿意,你可以用其他方式称呼它,但我认为这只是一个认知问题。如果您将此函数命名为setAgeByNotUsingSetter 感到更安全,那么我认为您只是在自欺欺人。
    猜你喜欢
    • 2019-11-26
    • 2023-03-07
    • 2021-09-21
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    • 2011-11-03
    • 2011-04-27
    • 1970-01-01
    相关资源
    最近更新 更多