为什么 PHP 中的抽象类方法需要与子类相同的签名?


Why do abstract class methods in PHP require same signatures as child classes?

我已经阅读了几个关于 PHP 中抽象类的线程,似乎没有一个答案可以解决我的问题:为什么抽象类中的方法需要与子类具有相同的签名(相同的参数),而无法知道这些抽象方法的子类实现可能需要什么?抽象类的经典示例类似于类 GeometricShape(),其中两个子类可能是类 Rectangle extend GeometricShape() 和类 Circle 扩展 GeometricShape()。getArea() 方法的一个需要长度和宽度作为参数,另一个只需要半径。这在 PHP 中应该如何工作?

lengthwidthradius不应该是方法的参数,它们应该是类中的属性。当你想获取一个对象的面积时,你只需调用:

$area = $shape->getArea();

Rectangle方法将返回length*widthCircle方法将返回pi*radius*radius

签名必须相同,因为此代码不知道它是在Circle还是Rectangle上运行,它需要等同地处理所有GeometricShape对象。

这是一个很好且有趣的问题。在像GeometricShape()这样的情况下,GetArea将没有参数。一个更好的例子是一个名为 FillColor 的抽象方法,它将颜色作为参数,如下所示:

abstract class GeometricShape
{
    abstract function GetArea();
    abstract function FillColor($color);
}

class Square extends GeometricShape
{
    function GetArea()
    {
        echo "Square - get area'r'n";
    }
    function FillColor($color)
    {
        echo "Square - Filling color $color'r'n";
    }
}

class Circle extends GeometricShape
{
    function GetArea()
    {
        echo "Circle - get area'r'n";
    }
    function FillColor($color)
    {
        echo "Circle - Filling color $color'r'n";
    }
}   
$square = new Square();
$square->FillColor('green');
$circle = new Circle();
$circle->FillColor('red');

抽象课是为孩子们提供一个共同的个性,孩子们可以超越。抽象类也可以提供子单元可以按原样使用的脚手架/基本属性。

如果抽象方法应该提供更宽松的签名,则可以向其发送一个数组。这样,圆形可以使用包含半径的数组覆盖该方法,而矩形可以发送具有长度和宽度的数组。方法主体将使用数组来确定已接收的内容以及如何处理它。

我认为您正在混合OOP各种概念

抽象化

当你的类必须为类及其子类提供概念限制时,抽象就会发挥作用。 例如,以现实世界为例,Tree是概念性的东西,直到它具体化为物理的,例如Apple Tree。如果你是自然主义者,你想保持自然的自然(不喜欢基因改造! 并确保Apple Tree确实生产苹果而不是芒果,并且确实有roots。现在关注术语 rootsfruit w.r.t Tree和 w.r.t Apple Tree 和任何其他Xyz Tree.当我们讨论这些关于Tree它们是非常开放的端接口时,每棵树都应该或必须被称为Tree(除非或直到它的GM树)。 Tree roots接口是抽象接口BCZ子类,即Apple Tree知道如何从地面吸取矿物质以制造apple fruit。因此,每个工厂都采用不同的方法来实现roots接口。

方法覆盖(getArea() 方法)

在你的例子中,getArea() 方法或多或少是方法覆盖的例子,其中孩子决定忽略/抑制其继承行为/属性的某些部分。

我希望这个自然的例子不是那么复杂