即使参数正确传递,参数也会错误[重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了即使参数正确传递,参数也会错误[重复]相关的知识,希望对你有一定的参考价值。

这个问题在这里已有答案:

当我跑这个时,它会抱怨

函数Base :: __ construct()的参数太少,在第18行的[FileName] .php中传递0,正好是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()正在调用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();
另一答案

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

(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();

这试图在__construct类中运行ChildA方法;从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();

以上是关于即使参数正确传递,参数也会错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

GET 参数为空,即使我正在传递一个值 [重复]

即使参数具有非空约束,也会收到有关可空类型参数的错误

Python - 如何使用池映射传递多个参数 [重复]

即使我的“Identity_nest_list”统一资源定位器包含 pk 参数,也会出现 NoReverseMatch 错误

即使 URL 包含参数,match.params 也会返回空

即使我只有一个参数,我也会收到“包装承诺不可迭代错误”