php7中的其他类型(正在扩展第一个类型的类)的覆盖属性类型(类)(类)

发布于 2025-01-25 12:53:59 字数 2065 浏览 1 评论 0原文

因此,我将一些数据结构定义为仅具有属性的PHP类(与C/C ++结构相似的语法)。 要以一种简单的方式键入严格,并且在一个地方拥有所有结构的常见属性 - 我认为将第一个基本结构定义为抽象类 - 它绝不应该实例化,所有“真正使用的”结构都将扩展它。工作示例:

// Parent struct def: Common data for all the shapes, not meant to be instantiated
abstract class Shape {
    public int $posX, $posY;
    public string $color;
}

// Real structure def: I would like to use this one in code a real structure
class Rectangle extends Shape {
    public int $width, $height;
}

然后,我尝试定义用于使用这些结构的类。概念非常相似:基本的抽象类具有所有结构常见的特征,一个子类将其扩展到每个结构。继续以前的工作示例:

abstract class ShapeRenderer {
    public Shape $shapeData;

    public function SetShapeData(Shape $shapeData) {
        $this->shapeData = $shapeData;
    }
}

class RectangleRenderer extends ShapeRenderer {
    public Rectangle $shapeData; // fatal error line

    public function SetShapeData(Rectangle $shapeData) { // warning here
        $this->shapeData = $shapeData;
    }
}

// init these variables for some testing after
$rect = new Rectangle();
$rect->width = 10;

$render = new RectangleRenderer();
$render->SetShapeData($rect);

可悲的是,我不能覆盖属性的属性$ shateata从摘要 shape 到正在扩展它的真实属性 - 矩形(与注释为“致命错误行” ”)给出:

Fatal error: Type of RectangleRenderer::$shapeData must be Shape (as in class ShapeRenderer)

所以我评论了这条线。当我将param类型从 shape 覆盖到更严格的矩形 shaperenderer 方法 setsephapeedata 时,仍然存在同样的错误。将父级方法更改为在 shaperender 中没有身体的一个没有身体的方法中,导致致命错误交换为警告:

Warning: Declaration of RectangleRenderer::SetShapeData(Rectangle $shapeData) should be compatible with ShapeRenderer::SetShapeData(Shape $shapeData)

代码似乎在起作用,我可以访问 $ render-> shapeedata-> width; dircotiy很好,但是当我尝试将整个 $ render-> shopateata >宽度。因此,显然不是很好的解决方案

,除了以下方法:

声明属性$ shateata,而无需指定其类型,只有一次 - 在常见的抽象类中 shaperenderer 删除$ shapatata的声明中的普通抽象类 shaperenderer (+所有代码在此处访问它),并仅在每个子类中声明它(使用任何类型) ? 这两种方式听起来不正确

So, I have defined some data structures as php classes with properties only (similar syntax to C/C++ struct).
To be type strict in an easy way and have properties common for all the structures in one place - I figured out to define first basic structure as abstract class - it should never be instantiated, and all the "really used" structures will be extending it. Working example:

// Parent struct def: Common data for all the shapes, not meant to be instantiated
abstract class Shape {
    public int $posX, $posY;
    public string $color;
}

// Real structure def: I would like to use this one in code a real structure
class Rectangle extends Shape {
    public int $width, $height;
}

Then, I tried to define classes for working with these structures. Concept was very similar: basic abstract class with features common for all the structures, and one child class extending it for each structure. Continuing previous working example:

abstract class ShapeRenderer {
    public Shape $shapeData;

    public function SetShapeData(Shape $shapeData) {
        $this->shapeData = $shapeData;
    }
}

class RectangleRenderer extends ShapeRenderer {
    public Rectangle $shapeData; // fatal error line

    public function SetShapeData(Rectangle $shapeData) { // warning here
        $this->shapeData = $shapeData;
    }
}

// init these variables for some testing after
$rect = new Rectangle();
$rect->width = 10;

$render = new RectangleRenderer();
$render->SetShapeData($rect);

Sadly, I cannot override type of inherited property $shapeData from abstract Shape to real one which is extending it - Rectangle (line with comment "fatal error line") gives:

Fatal error: Type of RectangleRenderer::$shapeData must be Shape (as in class ShapeRenderer)

So I commented that line. Still same error was happing when I did override param type from Shape to more strict Rectangle in ShapeRenderer method SetShapeData. Changing parent method to abstract one without a body in ShapeRenderer resulted in exchanging fatal error for a warning:

Warning: Declaration of RectangleRenderer::SetShapeData(Rectangle $shapeData) should be compatible with ShapeRenderer::SetShapeData(Shape $shapeData)

The code seems to be working, I can access $render->shapeData->width dirrectly just fine, but when i try to var_dump whole $render->shapeData it says that it's of type Shape and doesn't have property width. So it's clearly not the good solution

Is there any way to handle it other than:

declare property $shapeData without specyfing its type, only once - in common abstract class ShapeRenderer
remove declaration of $shapeData in common abstract class ShapeRenderer (+ all code accessing it there), and declare it only in every child class (using any type)
?
Both ways doesn't sound right to me

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文