构造函数中的 PHP 继承

问题描述 投票:0回答:1

我正在做测试。 鉴于此代码片段

<?php

class Point
{
    public $x;
    public $y;

    public function __construct($x, $y) {
        $this->x = $x;
        $this->y = $y;
    }
}

class Point3D extends Point
{
    public $z;

    public function __construct($x, $y, $z) {
        $this->z = $z;
    }
}

$p = new Point3D(1, 2, 3);
echo sprintf('(%d, %d, %d)', $p->x, $p->y, $p->z);

我很困惑,因为正确的答案似乎是:

(0,0,3)

但是$x和$y没有在子类中初始化。 __parent() 没有被调用 当我在沙箱中运行代码时,它确实给出了预期的答案 当我向 ChatGPT 询问此事时,他给出了我会给出的答案:$x, $y 之前未初始化... => 致命错误

问题是为什么我和ChatGPT都错了 这里面的原理是什么?

php inheritance
1个回答
0
投票

您的问题与类型化属性有关。当您没有像示例中那样使用类型化属性时,PHP 将尽力使用它所给定的内容。

使用相同的示例,我们可以使用类型提示来强制执行我们的期望,但无需调用父级

沙盒代码在这里

<?php
class Point
{
    public int $x;
    public int $y;

    public function __construct(int $x, int $y) {
        $this->x = $x;
        $this->y = $y;
    }
}

class Point3D extends Point
{
    public int $z;

    public function __construct(int $x, int $y, int $z) {
        $this->z = $z;
    }
}

$p = new Point3D(1, 2, 3);
echo sprintf('(%d, %d, %d)', $p->x, $p->y, $p->z);

输出:

Fatal error: Uncaught Error: Typed property Point::$x must not be accessed before initialization in /home/user/scripts/code.php:23
Stack trace:
#0 {main}
  thrown in /home/user/scripts/code.php on line 23

请注意,上面的致命错误指出了 typed 属性。通过使用强类型代码,PHP 将强制执行这些检查,并在遇到无法确定所提供类型的情况时抛出错误。

另请注意,除非您使用

declare(strict_types=1);
,否则即使在这种情况下传递字符串或其他非整数值,PHP 也会允许这些值通过并自动执行一些类型处理。

也就是说,一旦我们包含父构造函数,一切都将毫无问题地运行:

class Point3D extends Point
{
    public int $z;

    public function __construct(int $x, int $y, int $z) {
        parent::__construct($x, $y);
        $this->z = $z;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.