即使参数正确传递,参数错误也太少

  • 本文关键字:参数 错误 php
  • 更新时间 :
  • 英文 :


当我运行这个时,它抱怨

参数

太少,无法函数 Base::__construct((,在 [文件名] 中传递了 0.php在第 18 行,正好是预期的 1

class Base {
protected $var;
public function __construct($var){
$this->var = $var;
}
}
class ChildA extends Base {
public function handle(){
echo $this->var;
}
}
$base = new Base(10);
(new ChildA())->handle();

但正如你所看到的,我已经通过了:$base = new Base(10);

编辑:如回答和评论中所述,问题不在这里:

$base = new Base(10);

。但在这里:

(new ChildA())->handle();

我做错了什么?另外,我试图实现的是,有许多ChildX类需要扩展Base并且所有这些子类都必须具有$var属性。因此,与其在每个子类中复制$var,不如通过将键入工作放在父类中来减少键入工作。但显然,我的计划没有成功。

你的问题实际上是这一行:

(new ChildA())->handle();

请改为执行以下操作:

$child = new ChildA(10);
$child->handle();

无需单独实例化基类。

还有一件事。当父类和子类都有构造函数时,可以将parent::__construct($whatever);放入子类的构造函数中以运行父代码。

这是一个简单的类实例化概念,我认为你弄错了。

当你这样做时

$base = new Base(10);

您只创建Base类的实例。

但是,以下语句调用Child类的另一个实例。 请注意,基变量和此子实例是两个不同的实体,因此它们的行为不会相互影响。

(new ChildA())->handle();

因此,当前基变量的值为 10,但无法实例化handle()函数调用,因为它需要一个参数,该参数将提供给Base类的新实例。

您需要实例化子类,因此将首先调用继承类的构造函数并设置变量。然后,handle()函数可以成功返回正确的值。

$child = new Child(10); $child->handle(); //returns 10

扩展类时,默认情况下该类上的所有方法都存在于子类上,包括__construct等"魔术"方法。

所以当你写这个的时候:

class Base {
protected $var;
public function __construct($var){
$this->var = $var;
}
}
class ChildA extends Base {
public function handle(){
echo $this->var;
}
}

您的孩子类实际上看起来像这样:

class ChildA extends Base {
// Inherited property from Base class
protected $var;
// Inherited method from Base class
public function __construct($var){
$this->var = $var;
}
// New method in this class
public function handle(){
echo $this->var;
}
}

正如我们将在下面看到的,这是一个轻微的简化,但它解释了您的示例中发生的情况:

$base = new Base(10);

$baseBase类的实例;它与该类的任何其他实例以及ChildA类的任何实例完全分开。

(new ChildA())->handle();

这将尝试在ChildA类中运行__construct方法;从Base继承的方法的副本需要一个参数,但您没有提供一个参数,因此会出现错误。它期待你这样称呼它:

(new ChildA(10))->handle();

如果我们直接在子类中定义__construct,我们可以给它不同数量的参数:

class ChildB extends Base {
public function __construct() {
// Do nothing
}
public function handle(){
echo $this->var;
}
}
(new ChildB())->handle();

但是现在我们有一个不同的问题:Base类中的逻辑没有运行,所以$this->var永远不会设置为任何内容。

这就是我过度简化上面的事情的地方。实际上,父__construct方法和子__construct方法存在,它们只是相互"隐藏"。您可以使用语法parent::method访问父副本。

因此,您可以使用不带参数的构造函数创建一个子类,并且在运行该构造函数时,使用硬编码值10运行基构造函数:

class ChildC extends Base {
public function __construct() {
// Run the constructor in the Base class
parent::__construct(10);
}
public function handle(){
echo $this->var;
}
}
(new ChildC())->handle();

您的new ChildA()正在从 Base 调用构造函数,并且您没有在此处传递任何参数。

你在这里犯了错误:当你这样做new Base(10)你的$var不会传递给新的new ChildA()实例

在您的情况下,我会使用静态参数而不是构造函数值

class Base {
protected static $var;
public function __construct(){
}
public static function setVar($var) {
self::$var = $var;
}
}
class ChildA extends Base {
public function handle(){
echo self::$var;
}
}
Base::setVar(10);
(new ChildA())->handle();

最新更新