【问题标题】:Why are member variables usually private?为什么成员变量通常是私有的?
【发布时间】:2011-10-15 11:44:20
【问题描述】:

我今天刚开始学习面向对象编程,只是通过观察发现在所有示例中,成员变量都是私有的。为什么通常是这样?

// Class
class Building {
    // Object variables/properties
    private $number_of_floors = 5; // These buildings have 5 floors
    private $color;

    // Class constructor
    public function __construct($paint) {
        $this->color = $paint;
    }

    public function describe() {
        printf('This building has %d floors. It is %s in color.', 
            $this->number_of_floors, 
            $this->color
        );
    }
}

另外,如果你将成员变量声明为 public,那么在声明它的类之外访问它的语法是什么?

最后,你必须在类中的每个变量和函数前面加上“public”或“private”吗?

编辑:感谢大家的回答,谁能确认您是否必须在类中的每个变量和函数前面加上“公共”或“私有”?

谢谢!

【问题讨论】:

  • 听起来你需要读一本关于面向对象编程的书。你问了一些关于面向对象编程基础的非常好的、直接的问题。我没有足够的时间来获得完整的答案,所以我只会说查找EncapsulationInheritanceAbstraction

标签: php oop


【解决方案1】:

经验法则是尽量隐藏信息,仅在绝对必要时共享。

  • 俄罗斯编码人员有时会在不必要的广泛访问修饰符上说 Public Morozov,暗指有关不当信息披露以及由此造成的进一步惩罚的故事 - Pavlik Morozov

    一个 13 岁的男孩向当局告发他的父亲并被他的家人杀害......

【讨论】:

  • 这不是一个原则的例子吗? :)(与您对 Programers.SE 的评论有关,但它们是相关的 - 没关系)
【解决方案2】:

不能从外部访问私有变量,这给了你控制权。

但是如果你把它们公开,那么你可以像这样访问它

$your_object_instance->Your_variable

例如

$building = new Building();
echo $building->number_of_floors;

但你必须将你的 number_of_floors 变量公开,如果你想访问私有成员,那么你需要在 Building 类中实现新方法

public function getNumberOfFloors()
{
  return $this->number_of_floors;
}

所以你的代码应该是这样的

$building = new Building();
echo $building->getNumberofFloors();

【讨论】:

  • 感谢 Senad,那么您必须在类中的每个变量和函数前面加上“public”或“private”吗?
  • 对于方法,如果你不把私有或公有而不是你的方法是公有的,对于变量,如果你只是把 var $variable 然后它的公有。
【解决方案3】:

这是为了防止属性被直接从外部操纵,并可能使对象进入不一致的状态。

OOP 的基本原理之一是对象应负责维护自己的状态并保持其内部一致性,例如不允许将仅用于保存正整数的属性设置为 -343.239 或确保内部数组结构正确。这样做的可靠方法是使属性的值无法直接从外部设置。通过将属性设为私有,您可以防止外部代码直接操作它,强制它通过您为该作业编写的 setter 方法。这个 setter 可以检查提议的更改不会使对象进入不一致的状态,并防止任何可能的更改。

大多数针对初学者的书籍和示例都倾向于使用非常简单的对象,因此可能无法解释为什么您需要遍历所有私有属性以及 getter 和 setter,但随着对象复杂性的增加,好处越来越明显。不幸的是,复杂的对象也不太适合作为初学者的教具,所以一开始很容易忽略这一点。

【讨论】:

    【解决方案4】:

    我真的不知道如何回答这样的问题,但我按照php手册描述你最好

    属性或方法的可见性可以通过添加前缀来定义 带有关键字 public、protected 或 private 的声明。班级 声明为 public 的成员可以在任何地方访问。成员宣布 protected 只能在类本身中访问,并且可以通过 继承类和父类。声明为私有的成员只能是 由定义成员的类访问。

    属性可见性

    类属性必须定义为公共、私有或受保护。如果 使用 var 声明,该属性将被定义为 public。

    Methods declared without any explicit visibility keyword are defined as public.
    

    欲了解更多信息,请参阅Visibility

    【讨论】:

      【解决方案5】:

      Senad 的回答是正确的,因为将不希望外部方法访问的变量设为私有是一种良好的编程习惯。

      但是,内存管理/垃圾收集语言中的原因是,当您维护对对象的引用时,它无法被垃圾收集,并可能导致内存泄漏。

      希望这会有所帮助!

      【讨论】:

        【解决方案6】:

        这是为了让您更轻松地编写代码,并减少您出错的可能性。这个想法是只有类可以访问它的私有变量,所以代码中其他地方的其他类不能通过以意想不到的方式更改私有变量来干扰和搞砸一些事情。像这样编写代码,让一堆自治类通过少量严格控制的公共方法进行交互,似乎是一种更简单的编码方式。大项目更容易理解,因为它们被分成小块。

        【讨论】:

          【解决方案7】:

          将变量设为私有可避免调用代码依赖于类的实现细节,因此您可以在之后更改实现而不会破坏调用代码。

          您可以在同一行声明多个变量,并且只使用一次privatepublic

          private $number_of_floors = 5, $color;
          

          另请参阅 PHP 文档的“Classes and Objects”。

          【讨论】: