快速面向对象编程问题 - PHP

3
在面向对象编程中,有时你会看到类似于这样的内容:
$memberID = $system->members->memberID();

我对 ->members->... 这部分完全感到困惑,请问它是如何工作的?

例如,假设我有一个名为 $systems 的类,那么我该如何在后面加上 ->members-> 来运行 members 类呢?

我只知道如何进行以下操作:

$system = new system();
$memberID = $system->memberID();

但我想知道如何做到这一点:
$system = new system();
$memberID = $system->members->memberID();

谢谢!

-- 更新 -- 感谢所有帮助我到这一步的人!你们真的指导我走向了正确的方向,我现在有了一个很好的答案! :) 还要感谢编辑这个问题的版主,我对bbcode语法不熟悉,很抱歉。

我想要一个自动创建新类的东西,例如调用->members->时会自动使用__get()包含,而不必手动输入类似于“new members()”这样的内容。这有点难以解释,但我希望你能基本理解。

无论如何,这是我使用的代码:

<? class system {

public function __get($name){
    $file = 'lib/'.$name;
    if(file_exists($file)){
        require_once($file);
        $classname = $name;
        $this->$name = new $classname($this);
        return $this->$name;
    }else{
        die('Class '.$name.' could not be loaded (tried to load class-file '.$file.')');
    }
}

现在,如果我想做类似于这样的事情:

$system = new system();
$system->members->functionHere();

它会自动创建一个成员类的新实例并从lib文件夹中要求文件。 如果这违反了规则,那么我道歉。我只是想为那些在谷歌搜索时遇到这个问题的人发布此帖子,因为我知道我总是在这里着陆!
3个回答

3

$system变量保存着一个对象,其中包含一个名为$members的属性。而这个$members属性本身又保存着一个对象,它有一个$memberID属性。

$system = new system();
$system->members = new Members(); // or whatever it must be
$system->members->memberId();

1

当你看到这样的代码时,你就知道有人很可能做错了什么!

为了让这段代码正常工作,你需要授予一个对象的成员变量(前者存储一个对象)公共访问权限。

在大多数情况下,授予此类成员变量的公共访问权限是不好的实践。该变量应该只能通过getter访问(至少,它仍然会违反LoD)。

这段代码违反了封装原则和LoD(Demeter法则)。

[编辑]

为什么这几乎肯定是一个错误:

A)直接授予成员变量的公共访问权限在大多数情况下都是错误的,因为它使您的类的公共接口变得僵硬(难以更改)。如果您有一个getter,您可以随时更改成员的实现,getter仍将保持不变,您无需从任何地方更改调用。您永远不能为直接访问变量编写代理!另一方面,为getter编写代理很容易!

B) 直接公开成员变量的访问在大多数情况下都是一个错误,因为你让每个人直接与类内部的类交流!这很可能会导致当这两个类中任何一个的公共接口发生变化时,维护成本更高

[/编辑]


1
除了对变量进行额外操作之外,我看不出使用getter的理由 - 它是一个无用的中间人。当您在获取变量后执行某个特定过程时,这是可以理解的,但是让函数访问变量,并为此命名所有内容,这有什么意义呢? - Zirak
@Zirak:显然你不理解封装原则和迪米特法则。 - markus
2
你也不要只考虑眼前,这是工程领域的一个大错误! - markus
@Zirak,你只是个新手。多了解一下封装和接口。比如,可以看看这本书:http://www.amazon.com/Objects-Patterns-Practice-Experts-Source/dp/143022925X/ - OZ_
@Galen:您能解释一下您的不同意见吗? - markus
显示剩余4条评论

0

memberssystem 的对象属性,也是一个包含方法 memberID() 的对象。

要为您的对象分配属性,只需像这样做:

class System {
  function __construct() {
    $this->members = new Members();
  }

  // etc
}

或者

$systemObj = new System();
$systemObj->members = new Members();

这真的取决于您希望使用的上下文 :)

正如@markus所提到的,如果您要从外部访问属性,则必须声明为public。此外,使用setter/getter通常更好...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接