PHP :将调用$this的方法添加到现有类中


PHP : add methods calling $this to existing classes

我有一个容器类:

class ContainerClass {
    var $subobj;
    var $myName;
    function __construct($val, $name)
    {
        $this->myName = $name;
        $this->subobj = new ItemClass ($val);
    }
    function getItem()
    {
        return ($this->subobj);
    }
}

和一类:

class ItemClass {
    var $value;
    function __construct($val)
    {
        $this->value = $val;
    }
}

这两个类是假设库的成员,只需使用 include 调用即可在许多项目中使用该库。

在我的项目中,我需要做一些特定的显示,所以对于每个项目,我希望在不修改库源代码的情况下,添加如下方法(具有项目特定内容):

项目 1

对于ContainerClass

function getDisplay () {
   return ($myName . " : " . $this->subobj->getDisplay());
}

对于ItemClass

function getDisplay () {
   return (/* some display */ $this->value);
}
function getDisplayAlone () {
   return (/* some display */"<DIV>" .  $this->value . "</DIV>");
}

项目 2

对于容器类:

function getDisplay () {
   if ($this->value == 5) return ($myName . " : " . $this->subobj->getDisplay());
   return ("No luck !");
}

对于ItemClass

function getDisplay () {
   return (/* some display */"Go to hell !");
}
function getDisplayAlone () {
   return (/* some display */"<DIV>What's up doc ?</DIV>");
}

并且能够从每个项目中的主 php 文件中调用这些:

include "mylibrary.php";
$obj = new ContainerClass (10, "Me");
$obj->getDisplay();
$obj->getItem()->getDisplayAlone();

我找到了很多向类和对象添加方法的提示和技巧,但它们要么在 php5 上不起作用,要么不允许在方法中使用$this,要么根本不起作用。

有人可以帮助我实现这一目标吗?

假设这将是你的库类:

class ContainerClass 
{
    protected $subobj; //Must be protected to be accessable for the child classes
    protected $myName; //Must be protected to be accessable for the child classes
    function __construct($val, $name)
    {
        $this->myName = $name;
        $this->subobj = new ItemClass ($val);
    }
    function getItem()
    {
        return ($this->subobj);
    }
}
class ItemClass  {
    private $value;
    function __construct($val)
    {
        $this->value = $val;
    }
}

如果要为每个项目实现不同的函数,则需要重写库类。所以例如 Project1ItemClass将库扩展ItemClass类。下面是一个示例:

class Project1ItemClass extends ItemClass {
    function getDisplay () {
       return (/* some display */ $this->value);
    }
    function getDisplayAlone () {
       return (/* some display */"<DIV>" .  $this->value . "</DIV>");
    }
}
class Project1ContainerClass extends ContainerClass {
    //Override the constructor cause you want to create a project 1 specific ItemClass
    function __construct($val, $name)
    {
        $this->myName = $name;
        $this->subobj = new Project1ItemClass ($val);
    }
    function getDisplay () {
       return ($this->myName . " : " . $this->subobj->getDisplay());
    }
}

下面的示例将打印:qwe : asd

$Project1ContainerClass = new Project1ContainerClass("asd","qwe");
echo $Project1ContainerClass->getDisplay();

请注意,您应该在项目特定的ContainerClass中重写构造函数,因为您要在其中创建ItemClass的新实例。如果不重写构造函数,则正在创建ItemClass的实例,而您的意图是Project1ItemClass的实例。

使用 extends

项目 1

class ProjectItemClass extends ContainerClass {
    function getDisplay () {
        return (/* some display */ $this->value);
    }
    function getDisplayAlone () {
         return (/* some display */"<DIV>" .  $this->value . "</DIV>");
    }
}
class ProjectContainerClass extends ContainerClass {
    public function __construct($val, $name) {
        $this->myName = $name;
        $this->subobj = new ProjectItemClass ($val);
    }
    function getDisplay () {
        return ($myName . " : " . $this->subobj->getDisplay());
    }
}

项目 2

class ProjectItemClass extends ContainerClass {
    function getDisplay () {
        return (/* some display */"Go to hell !");
    }
    function getDisplayAlone () {
        return (/* some display */"<DIV>What's up doc ?</DIV>");
    }
}
class ProjectContainerClass extends ContainerClass {
    public function __construct($val, $name) {
        $this->myName = $name;
        $this->subobj = new ProjectItemClass ($val);
    }
    function getDisplay () {
        if ($this->value == 5) return ($myName . " : " . $this->subobj->getDisplay());
        return ("No luck !");
    }
}

确保在原始类之后包含/要求这些新类,然后像这样使用它们:

$obj = new ProjectContainerClass (10, "Me");
$obj->getDisplay();
$obj->getItem()->getDisplayAlone();

请注意覆盖__construct,以确保使用 ProjectItemClass 而不是 ItemClass 。您还可以使用 parent 调用来确保对扩展类构造的任何更改仍被使用(但$this->subobj只会被调用两次)。

public function __construct($val, $name) {
    parent::__construct($val, $name);
    $this->subobj = new ProjectItemClass($val);
}