对于usort不能做OOP回调函数(Cannot do OOP Callback function

2019-10-23 12:34发布

我已经通过使用类成员作为回调函数的几十讨论阅读,但没有一个例子地址是什么,在我看来是显而易见的OOP设计,基于与其他OOP语言如C ++和Java的工作。

我已经定义的类中的比较方法:

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中”,“比较”),但它不是直观的定义比较方法的静态函数班级。 基于超过30年的面向对象的个人经验静态函数是在大多数情况下,一流的设计很差的结果。 尤其是静态方法失利多态性。

我所寻找的是这样的Java,它利用了可比界面的排序功能。 我看到,已有一些讨论可以追溯到2010有关定义界面相媲美,但讨论仅与比较运算符连接,使得PHP较真的不舒服,因为它重载运营商。 然而在Java可比接口超载运营以来,与String类的明显的例外,Java不支持运算符重载。 Java实现了Comparable接口,您可以使用类SortedMaps和集合中的实例进行排序,但如果你想比较两个对象必须显式调用compareTo方法。 我也看到有是已经覆盖比较操作符的默认实现基本上无证compare_objects方法。 在尽管纯粹主义者的反对换句话说PHP已经允许你重载比较运算符的一类。 但是它是无证的PHP排序功能是否使用compare_objects当有人问到对象进行排序。

Answer 1:

你调用$这是你在课堂之外。

$obj = new TestClass();
$sorted = usort($instances, array($obj, 'compare'));

你也可以做这样的事情(未测试的代码)

class TestClass() {
    function compareWith($other) {
        $arr = array($this, $other);
        usort($arr, function($that, $other) {
            if ($other instanceof TestClass)
            {           // comparing two instances
            return $other->afield - $that->afield;
            }           // comparing two events
            else
                throw new Exception("parameter is not instance of TestClass");
        });
        return $arr;
    }
}

$instance1  = new TestClass();
$instance2  = new TestClass();
$sorted = $instance1->compareWith($instance2);


Answer 2:

您在您的评论中提到的集合类 - 所以这里的使用(一个非常基本的)之一,从我所提到的手册中的用户评论排序采取的方法相结合的例子:

class Collection {
  private $itemType;
  private $items;

  public function __construct($itemType) {
    $this->itemType = $itemType;
    $this->items = [];
  }

  public function add($item) {
    if($item instanceof $this->itemType) {
      $this->items[] = $item;
    }
    else {
      throw new Exception('Only items of Type ' . $this->itemType . ' can be added!');
    }
  }

  public function sort() {
    usort($this->items, array($this, 'compareItems'));

    var_dump($this->items); // test output, to check the result
  }

  private function compareItems($a, $b) { // calls the compare method of the item class
    return $a->compare($b);
  }
}


class TestClass {
  private $aField;

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

  public function compare($other) {
    if($other instanceof TestClass) {
      return $this->aField - $other->aField;
    }
    else {
      throw new Exception('Parameter is not instance of TestClass!');
    }
  }
}

$collection = new Collection('TestClass');

$collection->add(new TestClass(5));
$collection->add(new TestClass(1));
$collection->add(new TestClass(3));

$collection->sort();


文章来源: Cannot do OOP Callback function for usort
标签: php oop