【问题标题】:Why do abstract class methods in PHP require same signatures as child classes?为什么 PHP 中的抽象类方法需要与子类相同的签名?
【发布时间】:2013-09-06 03:57:00
【问题描述】:

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

【问题讨论】:

    标签: php abstract-class


    【解决方案1】:

    lengthwidthradius 不应该是方法的参数,它们应该是类中的属性。当你想得到一个物体的面积时,你只需调用:

    $area = $shape->getArea();
    

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

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

    【讨论】:

      【解决方案2】:

      这是一个很好且有趣的问题。在像 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');
      

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

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

      【讨论】:

        【解决方案3】:

        我认为你在混合 OOP 的各种概念

        抽象

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

        方法覆盖(getArea() 方法)

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

        我希望这个自然的例子没有那么复杂

        【讨论】:

        • 我不确定你为什么得到 -1。从我的角度来看,您的答案与问题没有直接关系,但它仍然很有用。 +1 给你。您的散文将对 PHP 新手有所帮助。
        猜你喜欢
        • 2017-01-04
        • 2014-08-29
        • 1970-01-01
        • 2022-07-20
        • 1970-01-01
        • 2012-12-20
        • 2021-06-03
        • 1970-01-01
        • 2018-12-15
        相关资源
        最近更新 更多