【问题标题】:PHP Pass Instance Of Object To Abstract Class ConstructorPHP将对象的实例传递给抽象类构造函数
【发布时间】:2014-10-11 15:48:48
【问题描述】:

为了加深我对 OOP 的理解,我决定使用抽象类重构我的一些代码。思路大致;

  • 一个“父”抽象类构成所有子类扩展的基础。
  • 一个“助手”类,其中包含抽象类的子类需要的一系列方法。
  • “助手”类将被其他类使用,所以我不希望它成为抽象类的一个组成部分。

问题;

子类按预期扩展了抽象类,但 PHP 警告我抽象类的构造函数中缺少 $helper 参数。我相信构造函数被调用是因为我的子类中没有构造函数,这很好,但是由于您不直接调用抽象类,我该如何让它工作?示例代码如下;

abstract class Parent_Abstract
{
    public $input_helper_methods;

    public function __construct( $helpers = NULL )
    {

        //set the helper methods
        $this->input_helper_methods = $helpers;

    }
}

变量$helpers 目前在另一个文件中,该文件包含在抽象类文件的顶部。同样,我认为这是如何完成的问题。当我了解结构后,我想使用自动加载器,但现在,手动就可以了。这是那个文件的内容;

class RD_Form_Input_Helper_Methods
{
    private $var = 'something';
}

$helpers = new RD_Form_Input_Helper_Methods;

我希望这是有道理的。感谢您花时间阅读/回复。

另一个例子;

//"helper" classes. I would like these methods to be available to Child_One and Child_Two
class Helper_Functions {}

class Formatting_Functions {}


abstract class Parent_Abstract()
{
    private $helper_functions;
    private $formatting_functions;

    public function __construct( $object_one, object_two )
    {
        $this->helper_functions = $object_one;
        $this->helper_functions = $object_two;
    }

}

class Child_One extends Parent_Abstract 
{
    //I can use any of the properties or methods from the Helper_Functions or Formatting_Function class
}

class Child_Two extends Parent_Abstract 
{
    //I can use any of the properties or methods from the Helper_Functions or Formatting_Function class
}

【问题讨论】:

  • 不。我在下面的答案中看到了您的回复并在那里回复。

标签: php class dependency-injection abstract-class abstract


【解决方案1】:

子类按预期扩展了抽象类,但 PHP 警告我抽象类的构造函数中缺少 $helper 参数。

如果抽象类构造函数需要$helper 参数,您只会收到这样的警告。但是你的代码不一样,$helper参数是可选的:

abstract class Parent_Abstract
{
    public $input_helper_methods;

    public function __construct( $helpers = NULL )
    {                            ###############      $helpers is optional

现在我引用它时,它还有一个不同的名称 $helper =/= $helpers

因此,您在问题中提供的代码示例很可能不完整且存在错误。

让我们根据您的问题概述一个新的模型:

abstract class AbstractBaseClass
{
    private $helper;

    function __construct($helper)
    {
        $this->helper = $helper;
    }
}

class Concrete extends AbstractBaseClass
{
}

简而言之:$helper 字段(或属性)是 private 而不是 public$helper ctor 参数是必需的。

使用该代码并实例化一个具体的子类会给出您所说的错误:

// Warning: Missing argument 1 for AbstractBaseClass::__construct()

$obj = new Concrete();

那是因为缺少助手。为了简单起见,让我们假设帮助器实际上是您在复杂计算中需要的一个秘密数字,所有这些都是由这些具体类完成的。号码是42

$obj = new Concrete(42);

现在错误消失了。并且 helper 字段已正确初始化:

print_r($obj);

Concrete Object
(
    [helper:AbstractBaseClass:private] => 42
)

如你所见,抽象类的private字段已经设置好了。助手(此处为数字 42)已分配给它。

【讨论】:

    【解决方案2】:

    你要找的是static variables

    在本例中,我使用了一个名为 $text 的变量,而不是原来的 $helpers。该变量一旦设置,在所有子类中将是相同的。

    使用public static 变量定义一个抽象类。此外,还可以选择定义getter function,这将允许您访问静态变量的值作为每个子类的属性。

    abstract class Parent_Abstract
    {
    
        public static $text;
    
        public function __get($name)
        {
            // return the static variable's value
            return $name == 'text' ? self::$text : null;
        }
    }
    

    定义 2 个子类:

    class Child1 extends Parent_Abstract
    {
    
    }
    
    class Child2 extends Parent_Abstract
    {
    
    }
    

    现在来测试...设置静态变量的值,然后实例化子类并检查每个对象上$text的值;

    Parent_Abstract::$text = 'hello world';
    
    $child1 = new Child1();
    $child2 = new Child2();
    
    echo $child1->text . "\n";
    echo $child2->text;
    

    您会看到两个孩子的值相同。

    【讨论】:

    • 您好,感谢您的回复。我以前试过这个,它工作正常。我试图将 $helpers 对象直接传递给抽象类,所以我不必通过子类传递它,尽管我想我只需要传递一次?令人困惑...
    • @Dan:你的评论让我有点疑惑:如何你将$helpers 直接传递给抽象类?抽象类通常不“存在”。 - 但如果我现在对你说:你通过继承传递到那里(parent::...)并且你只传递一次,因为只有一个对象,而不是传递。它只是抽象基类和扩展类的复合物,但它是一个对象。在运行时,您通常不会太在意。对于应用程序来说,是否有基类没有区别。
    • @hakre - 我理解抽象类不“存在”的想法。也许我的头是做不到的?我想把一个类的功能和抽象类结合起来,然后继承它。
    • Drahcir:我非常确定@Dan 不是在寻找静态变量
    • 好吧,伙计们,我想问题要容易得多。并且不要将语言功能扔给它,只需尝试使用更基本的元素对其进行分类。尽可能远离静态、特征等。基本的继承、可见性和可能抽象基类/接口的概念对于初学者来说已经很重要了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多