【问题标题】:Abstract method with variable list of arguments in PHPPHP中具有可变参数列表的抽象方法
【发布时间】:2017-11-04 05:41:26
【问题描述】:

我在 PHP 的 OOP 中遇到了一个问题。我试图实现一个抽象的父类方法,并且从子类中,我必须将它与可变数量的参数一起使用。

这是抛出的错误:

PHP 致命错误:Square::getArea($length) 的声明必须与 Shape::getArea() 兼容

还有课程:

abstract class Shape {
    abstract protected function getArea();
}

class Square extends Shape {

    public function getArea($length)
    {
        return pow($length, 2);
    }

}

class Triangle extends Shape {

    public function getArea($base, $height)
    {
        return .5 * $base * $height;
    }

}

我可以使用孩子的__construct() 方法在启动时设置不同形状的属性,但我想知道是否存在另一种方法并允许我定义变量参数列表。

提前致谢。

【问题讨论】:

  • I could use the child's __construct() methods to set the properties of the different shapes at the initiation time 这确实是最好的方法
  • 但是您也可以在 getArea() 方法中使用 func_get_args() 而无需在方法定义中指定参数
  • 我不太喜欢func_get_args()。我觉得有点脏。正如您所说,我将保留构造方法,这是最好的方法。感谢 cmets @MarkBaker
  • 另一种选择是使用 splat 运算符对 getArea(... $dimensions) 的所有 getArea() 方法(包括摘要中的方法)使用单个参数;其次是 list($base, $height) = $dimensions; 作为方法的第一行
  • 还要注意,如果您的摘要中有空方法,那么您实际上并不是在制作抽象,而是在制作接口。

标签: php oop inheritance methods abstract


【解决方案1】:

正如在您提到的问题下的 cmets 中,有几种方法可以解决您的问题。

类属性和构造函数 在我看来,这将是最简单的方法。它既简单又智能。

interface Shape
{
    protected function getShape();
}

class Square implements Shape
{
    protected $length;

    public function __construct(int $length)
    {
        $this->length = $length;
    }

    protected function shape()
    {
        return pow($this->length, 2);
    }
}

class Triangle implements Shape
{
    protected $base;

    protected $height;

    public function __construct(int $base, int $height)
    {
        $this->base = $base;
        $this->height = $height;
    }

    protected function getShape()
    {
        return .5 * $this->base * $this->height;
    }
}

每个类都实现了 Shape 接口。 getShape 方法没有属性。属性是类本身的受保护属性。在调用特定类的构造函数时设置这些属性。

【讨论】:

    【解决方案2】:

    我认为使用__construct 的想法确实是最好的方法。这是为了什么。您希望每个形状都不同,并且每个形状必须以不同的方式计算面积。因此,多态性和 OOP 设计原则。

    说是的,总会有其他的黑客攻击。我不推荐这种方法,但如果需要,您可以使用它。本质上是传入一个数组,其中包含您想要的部分的键并使用它们。

    abstract class Shape {
        abstract protected function getArea($data = null); //Default to null incase it is not passed.
    }
    
    class Square extends Shape {
    
        public function getArea($data) //$data should have a length key
        {
            if(isset($data)){
                return pow($data['length'], 2);
            }
        }
    
    }
    
    class Triangle extends Shape {
    
        public function getArea($data) //$data should have a base and height key
        {
            if(isset($data)){
                return .5 * $data['base'] * $data['height'];
            }
        }
    
    }
    

    【讨论】:

    • 感谢您的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 2015-01-19
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    相关资源
    最近更新 更多