3

我想在基类中定义一次方法,然后在类层次结构中的连续构造函数中调用它。每次调用它时,我都希望它对调用它的类的属性进行操作。

例如,A 是基类,方法在这里定义。B从A继承,C从B继承。

当我实例化具体类 C 时,构造函数将调用基类方法,并且我希望它对 C 的属性进行操作。(这将是一个私有数组,我将在初始化它时填充它)。

然后 C 的构造函数调用parent::__construct. 当 B 构造函数调用基类方法时,该方法应该对 B 的属性进行操作。在 B 构造函数完成之前,它会调用parent::_construct,而 A 构造函数将对 A 的属性进行操作。

我正在研究 LSB,但它无法正常工作,因为parent::__construct它是一个转发呼叫。我尝试使用get_parent_class()代替的结果parent::,但我的错误调用static::propertyName因为propertyName不是常数。

我怎样才能做到这一点?

编辑:这是一个代码示例。下面的代码输出“PQPQP Q”。我希望它输出“PQRST U”。

class A {
    private $property = array('P','Q');

    function __construct() {
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

class B extends A {
    private $property = array('R','S');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }
}

class C extends B {
    private $property = array('T','U');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }
}

$c = new C();
4

4 回答 4

1

据我所知,这是不可能的。在私有的情况下,该变量不可用于方法,而在公共/受保护的情况下,其被覆盖。

你可以通过传递得到你想要的结果

$this->property

在这样的每个 myMethod 调用中-

$this->myMethod($this->property)

并相应地更改您的 myMethod 定义。

于 2012-08-06T14:32:48.663 回答
0

如果我没听错,这就是你的例子:

class A {
    public function __construct() {
    }

    public function someMethod($arg) {
        $someProperty = $arg;
    }
}

class B extends A {
    public function __construct() {
        parent::__construct();
    }
}

class C extends B {

    private $someProperty;

    public function __construct() {
        parent::__construct();
    }
}

一切都如您所愿。只有一个问题;A 类没有属性someProperty。如果你想在 A 类中使用它,你必须在那里定义它。如果你想在子类中使用它,你必须 make it protected。因此,您的 A 类必须如下所示:

class A {

    protected $someProperty;

    public function __construct() {
    }

    public function someMethod($arg) {
        $this->someProperty = $arg;
    }
}

现在您可以在 B 类和 C 类中使用它,A 类可以使用该属性someMethod

$instance = new C();
$instance->someMethod("test");
于 2012-08-02T06:38:48.553 回答
0

因为您的示例已$property定义为private并且您从不覆盖myMethod,所以当实例化类型为Cor的对象时B,它会运行 class的构造函数,该构造函数从值为is的类A调用。myMethod()A$propertyarray('P', 'Q');

如果您希望它打印“PQRST U”,则必须覆盖myMethod()并从每个单独的类的__construct()方法中调用它,或者声明$propertyprotected以便子类可以覆盖其值。

像这样的东西:

class A {
    private $property = array('P','Q');

    function __construct() {
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

class B extends A {
    private $property = array('R','S');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

class C extends B {
    private $property = array('T','U');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

$c = new C();

或这个:

class A {
    protected $property = array('P','Q');

    function __construct() {
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

class B extends A {
    protected $property = array('R','S');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }
}

class C extends B {
    protected $property = array('T','U');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }
}

$c = new C();
于 2012-08-06T14:37:59.093 回答
0

proptery不能在子类中重载。一旦有了C,它就不再具有 的私有属性A。它无法访问它们(反射之外)。您能够做到这一点的唯一方法是将属性传递到someMethod链中,但这需要访问所需的属性。

使用protected也不起作用,因为这样子级只会覆盖父级属性。

对此的解决方案不是必须C a (is-a),而是具有(has-a .. composition)C的属性。A但是,这需要对您的层次结构进行一些修改,并且您的调用必须更加明确。就像是

class C {
   private $b;
   private $properties = array('T', 'U');
   public function __construct(B $b) {
      $this->b = $b;
   }
   public function someMethod() {
      $this->b->someMethod($properties);
   }
}
class B {
   private $properties = array('R', 'S');
   private $a;
   public function __construct(A $a) {
      $this->a = $a;
   }
   public function someMethod($properties) {
      $this->a->someMethod(array_merge($this->properties, $properties));
   }
}
class A {
   private $properties = array('P', 'Q');
   public function someMethod($properties) {
      //your implementation plus an array_merge
   }
}

这显然会增加定义中的冗长,这是不好的。你可能想重新考虑为什么你必须以你正在做的方式做一些事情。你可以用traits 解决这个问题(假设你有 PHP 5.4)

于 2012-08-06T14:46:42.507 回答