php - 类扩展替代方案

时间:2013-10-23 21:41:02

标签: php

我有一个主要类,我在十几个子类中添加类似于Example#2。

我想知道是否有更好的方法来实现这一目标。我知道我可以对类进行“扩展”(例如#1)但是为了能够有一个变量可以访问所有扩展类函数,我必须“菊花链”扩展,然后创建一个新类关于最后一个扩展的参考 - 这个选项不是我想要的。

Example #1:

class main {
    function _construct(){}
    function main_function1(){}
    function main_function2(){}
}
class child1 extends main{
    function _construct(){}
    function child_function1(){}
    function child_function2(){}
}
class child2 extends child1 {
    function _construct(){}
    function child_function3(){}
    function child_function4(){}
}
$main = new child2();
$main->child_function1();
$main->child_function2();
$main->child_function3();
$main->child_function4();

这是我目前正在做的事情。

Example #2:

<?php

class main {
    function _construct(){}
    function main_function1(){}
    function main_function2(){}
}
class child1 {
    function _construct($main){$this->main = $main;}
    function child_function1(){}
    function child_function2(){}
}
class child2 {
    function _construct($main){$this->main = $main;}
    function child_function3(){}
    function child_function4(){}
}
$main = new main();
$main->child1 = new child1($main);
$main->child2 = new child2($main);

$main->child1->child_function1();
$main->child1->child_function2();
$main->child2->child_function3();
$main->child2->child_function4();

?>

示例#2是实现我正在寻找的最佳方式吗?

3 个答案:

答案 0 :(得分:1)

通过

class child {
    function __construct($main){$this->main = $main;}
}

示例2 中,您可以将$main实例作为child的属性传递给构造函数。在我看来,如果$main是一个为child提供信息的容器,这是有道理的 - 如果你想避免使用包含许多参数的构造函数,这将非常有用。根据您的命名,main看起来不像容器。请注意,您正在childmain之间创建依赖关系,因为如果您要实例化child,则需要提前main的实例!您在示例2 中所做的工作是创建circular references

$main = new main();
$main->child1 = new child1($main);
$main->child2 = new child2($main);

您可以拨打$main->child1->main,这意味着mainchild之间的高度耦合。所以我宁愿不说“去做例2”。

在你的情况下,它听起来像child实际上 main的一个特例,就像水果(主要)和苹果(孩子)之间的关系一样。这使得使用extends更加合理。您似乎不确定,因为您有许多扩展main的子类。对我来说这听起来很正常,如果所有child类都有类似的目的并且共享一些由main提供的基本功能。但我不太确定你的目标是什么。

答案 1 :(得分:0)

扩展类可能会破坏封装,因此根据您的类,最好将对象保持分离,如示例#2所示。你可以使用加载函数来简化主类的设置:

class main {
    function load($class){
        $this->$class = new $class();
    }
}
$main = new main();
$main->load('child1');
$main->child1->child_function1();

答案 2 :(得分:-1)

在php中,您有两个选择。 (在2020年)按照第一个答案的建议或在PHP中将您的Helper类注入另一个类,您可以使用traits

特性类似于类,但是它们的构造函数不能是公共的。 在特征上使用依赖注入很难,但是特征可以使用方法扩展现有的类,并且它们可以访问各自类的父方法。

无论如何,使用特征不能覆盖父方法,只能将方法添加到堆栈中。

特征的另一个缺点是,当您使用包含类的父方法时,在某些IDE中不完全支持类型提示。因此,为了使类型提示正常工作,您将需要一些解决方法。