【发布时间】:2015-06-26 22:31:20
【问题描述】:
我已经阅读了几十篇关于将类成员用作回调函数的讨论,但没有一个示例涉及在我看来是显而易见的 OOP 设计,它是基于与 C++ 和 Java 等其他 OOP 语言一起使用的。
我在类中定义了一个比较方法:
class TestClass {
private $aField; // integer value
function _construct($value)
{
$this->aField = $value;
} // TestClass::_construct
function compare($other)
{
if ($other instanceof TestClass)
{ // comparing two instances
return $this->afield - $other->afield;
} // comparing two events
else
throw new Exception("parameter is not instance of TestClass");
} // TestClass::compare
} // class TestClass
$instances = array(new TestClass(5),new TestClass(3));
// the following fails because:
// 1. $this is not defined outside a class member
// 2. compare does not take two parameters
usort($instances, array($this, 'compare'));
// the following kluge works around this
function order($this, $that) { return $this->compare($that); }
usort($instances, 'order');
我可以在这个论坛和 PHP 文档中找到的所有示例都不完整,因为它们没有显示调用 usort 的上下文。现在我可以通过使比较函数成为具有两个参数的静态函数并将其作为可调用数组('TestClass','compare')调用来解决这个问题,但是将比较方法定义为的静态函数并不直观班上。基于 30 多年的 OOP 静态函数的个人经验,在大多数情况下是糟糕的类设计的结果。尤其是静态方法会破坏多态性。
我正在寻找的是一个类似于 Java 的排序函数,它利用了 Comparable 接口。我看到早在 2010 年就有一些关于定义 Comparable 接口的讨论,但该讨论仅与比较运算符有关,并且使 PHP 纯粹主义者感到不舒服,因为它重载了运算符。然而,Java Comparable 接口不 重载运算符,因为除了 String 类的明显例外,Java 不支持重载运算符。在 Java 中实现 Comparable 接口使您可以使用 SortedMaps 中的类并对 Collection 中的实例进行排序,但是如果您希望比较两个对象,则必须显式调用 compareTo 方法。我还看到有一个基本上未记录的 compare_objects 方法,它已经覆盖了比较运算符的默认实现。换句话说,尽管有纯粹主义者的反对,PHP 已经允许您为一个类重载比较运算符。但是,当要求对对象进行排序时,PHP 排序函数是否使用 compare_objects 没有记录。
【问题讨论】:
-
看看这个用户评论,php.net/manual/en/language.oop5.object-comparison.php#85606——它可能并不完全是你所追求的,但至少它提供了一种在某些情况下可能有用的解决方法。