PHP中的类模板类似于C++中的类模板

5
在PHP中是否可以像C++一样创建类模板?PHP可能没有类似的语言结构(例如C++中的template关键字),但也许有某些聪明的技巧可以实现类似的功能?
我有一个Point类,我想将其转换为模板。在类中,我使用了类型参数,因此,对于要传递给Point方法的每个类,我都希望创建一个具有适当类型参数的新的Point类副本。
以下是C++示例:
#include<iostream>

template <typename T>
class Point
{
    public:
    T x, y;

    Point(T argX, T argY)
    {
        x = argX;
        y = argY;
    }
};

int main() {
    Point<int> objA(1, 2);
    std::cout << objA.x << ":" << objA.y << std::endl;

    Point<unsigned> objB(3, 4);
    std::cout << objB.x << ":" << objB.y << std::endl;

    return 0;
}

在PHP中是一样的,但它根本不起作用(当然,倒数第二行会返回一个错误):
class SomeClass
{
    public $value;

    public function __construct($value = 0)
    {
        $this->value = $value;
    }
}

class OtherClass
{
    public $value;

    public function __construct($value = 0)
    {
        $this->value = $value;
    }
}

class Point
{
    public $x;
    public $y;

    public function Point(SomeClass $argX, SomeClass $argY)
    {
        $this->x = $argX;
        $this->y = $argY;
    }
}

$objA = new Point(new SomeClass(1), new SomeClass(2));
echo $objA->x->value . ":" . $objA->y->value . PHP_EOL;

$objB = new Point(new OtherClass(3), new OtherClass(4));
echo $objB->x->value . ":" . $objB->y->value . PHP_EOL;

公共函数Point()应该是公共函数__construct()。 - Brice
1个回答

3
最好的方法是使用PHP的类似于eval的功能,通过这种方式可以实例化对象:
$className = 'SomeClass';
$obj = new $className;

这个,再加上空灵的动态类型,应该足以允许:
$objA = new Point('SomeClass', 1, 2);
echo $objA->x->value . ":" . $objA->y->value . PHP_EOL;

$objB = new Point('OtherClass', 3, 4);
echo $objB->x->value . ":" . $objB->y->value . PHP_EOL;

必要的定义可能如下所示:
class Point
{
    public $x;
    public $y;

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

我不确定是否推荐这种代码风格。你最初的做法似乎更清晰、更简洁。如果你愿意,可以在Point构造函数内执行一次检查,确保两个参数具有相同的类型。


2
我会直接传入 $argX$argY 而不指定类型 - PHP 是动态类型的,所以试图在这方面复制 C++ 没有太大用处。如果你想的话,可以在构造函数中检查两个参数的类型是否相同(即如果它们是对象,则检查它们的类是否匹配),如果不匹配则抛出异常。 - CompuChip
1
@CompuChip:他希望$x$y成员是某种类型的实例,分别使用$argX$argY作为构造函数参数。我不知道如果不知道类型,你怎么能做到这一点。除非他只是使用他已经开始编写的代码... - Lightness Races in Orbit
他写了$objA = new Point(new SomeClass(1), new SomeClass(2)); 作为一个例子,所以需要传递已实例化的对象。你要做的就是检查它们是否是相同的类型。 - CompuChip
@CompuChip:你有没有仔细阅读问题?你应该认真阅读问题,特别是他试图模仿的C++示例。(请注意,在他的C++示例中,ctor参数中的隐式转换在我的PHP示例中必须重新实现)不过,如果你愿意,可以写出自己对比的答案! - Lightness Races in Orbit
我阅读了这个问题,注意到C++代码正确地表示了在C++中执行此操作的方式,然后指出C++和PHP是非常不同的语言,因此在PHP中执行此操作的方式通常是不同的。由于您最初写道“我不确定我会推广这种代码风格”,并且您已经将我的评论要点添加到您的答案中以提供替代方案,我认为没有必要再提供另一个答案来重申您的最后一句话 :) 我认为观点已经表达清楚,OP应该自己决定,或者如果他想要的话可以要求澄清。 - CompuChip

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接