【问题标题】:Why Directly Accesing property is not recommended in OOPs PHP?为什么在 OOPs PHP 中不推荐直接访问属性?
【发布时间】:2010-04-22 05:33:05
【问题描述】:

如果我有一个带有属性 $name 及其 getter(get_name()) 和 setter(set_name()) 方法的类“person”,那么在实例化对象并设置属性之后,即

$paddy = new person();

$paddy->set_name("Padyster Dave");

echo "Paddy's full name: ".$paddy->name; //WHY THIS IS NOT RECOMMENDED...

在上面的代码$paddy->name;为什么不建议这样做

编辑

上面的代码是一个示例代码,没有分配任何访问器。它只是为了理解 $paddy->name 概念

【问题讨论】:

  • 在这方面的一个流行词:信息隐藏en.wikipedia.org/wiki/Information_hiding 而您要求的内容通常适用于 OOP 而不仅仅是 PHP。
  • 我使用了 php 的语法并将问题标记到 PHP 部分,这就是为什么添加关键字 PHP,我知道这个事实,它对许多人来说都是通用的..Thanksss

标签: php oop


【解决方案1】:

奇怪的是,您有一个 setter,但要离开属性 public。 (假设没有 __get 魔法发生。)

您通常希望使用 getter/setter 来更好地控制什么可以分配给属性,什么不能。或者,您可能希望在访问或更改属性时执行代码。无论哪种情况,您都应该通过设置属性privateprotected 来强制使用getter/setter,否则就毫无意义。这是为了防止您自己或其他将使用该课程的人射击自己的脚。

如果您的示例中的设置器只设置值而不做任何其他事情,那是多余的。如果它确实执行了设置值时需要的其他操作,那么您的类设计存在缺陷,因为可以在不使用 setter 的情况下更改值。


class Foo {
    public $bar = 0;  // is only allowed to contain numeric values
    public function setBar($val) {
        if (is_numeric($val)) {
            $this->bar = $val;
        }
    }
}

$obj = new Foo();
$obj->bar = 'some value'; // set a string, which is not allowed

如果你让$barprotected,那是不可能的。

【讨论】:

  • “如果它确实做了设置值时需要的其他事情,那么你的类设计就有缺陷,因为可以在不使用 setter 的情况下更改值。”你能详细说明一下吗?请
  • @Parth 如果你这样做protected $bar = 0;$obj->bar 是不允许的,会抛出一个警告。阅读:php.net/manual/en/language.oop5.visibility.php
【解决方案2】:

因为您可能有一天会摆脱 $name 成员,将其替换为(例如)$first_name$last_namefullname() 方法(不是那是 good idea)。当然,有了__get and __set,就没那么重要了。

更一般地说,设置属性可能不像存储值那么简单。直接访问成员字段可能会导致其他函数导致对象处于不一致状态。想象一下,您存储了一个需要保持排序的数组;如果该数组是公开的,则其他东西可以将未排序的数组分配给该字段。

【讨论】:

    【解决方案3】:

    暴露公共字段将是一个坏习惯。来自good artical关于PHP中的OO原理

    如果对象发生任何变化,则使用它的任何代码也需要更改。例如,如果要将人的名字、家庭和其他名称封装在 PersonName 对象中,则需要修改所有代码以适应更改。

    【讨论】:

      【解决方案4】:

      显然我也在做“坏”的事情,因为我一直使用这种代码。

      但是如果 $this->name(或者我会做的 $this->nameFormatted)的构造如下:

      protected var $name;
      $this->name = $this->getSalutation() . ' ' . $this->nameFirst . ' ' . $this->nameLast;
      

      或类似的东西。

      您在公共上下文中使用 $this->name out,但它仍然在类中构造,如果它受到保护,则不会被覆盖。

      或者我错过了重点,“坏”的事情实际上是在公共范围内设置名称?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-18
        • 2011-03-05
        • 1970-01-01
        • 2012-11-16
        • 2014-08-03
        • 2011-07-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多