方法链接和类继承

时间:2014-01-14 11:44:31

标签: php oop inheritance method-chaining

我认为我或多或少能够掌握OOP /继承,并且方法链的基础知识我认为我也理解。但是我仍然对如何实际使用它们感到困惑。

我想做一些我以前在使用Magento时看到的东西: 在Magento中,我看到了某种方法链中使用的“选择器函数”。这有点难以言喻,但它有点像:

$categoryName = Mage::getModel('catalog/category')->load($categoryId)->getName();

这是我感兴趣的load($categoryId)部分,例如,一个选择某个实例的函数,并允许我在该特定实例上运行函数。

现在,我正在编写一个模块,允许我在我们的网站上配置某些促销活动。看到我们将有许多不同的促销活动,我希望它们易于配置和修改,我想做类似的事情。

所以,如果我想做这样的事情:

$prm = new Promotion();

$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');

$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
$prm->getPromo('nyPromo')->setName('Promotion for New Years!');

echo $prm->getPromo('xmasPromo')->getName(); // returns: Promotion for Xmas!
echo $prm->getPromo('nyPromo')->getName(); // returns: Promotion for New Years!

该类的定义必须如何?

这可能比我预期的要简单得多或复杂得多。在任何一种情况下,非常感谢!


编辑: 所以我做了一些关于deceze给我的测试,但我仍然感到困惑。 错误命名并将2个类放在1个文件中,这就是我所做的:

类文件:

class Promotion {
    private $__arr = array();
    public function addPromo($name) {
        $this->__arr[$name] = new Promo();
    }
    public function getPromo($name) {
        $this->__arr[$name];
    }
}

class Promo {
    private $name;
    public function setName($name) {
        $this->name = $name;
    }
    public function getName() {
        return $name;
    }
}

和运行文件:

require_once 'class.php';
error_reporting(E_ALL);

$prm = new Promotion();

$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');

$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
$prm->getPromo('nyPromo')->setName('Promotion for New Years!');

echo 'X: '.$prm->getPromo('xmasPromo')->getName(); // returns: Promotion for Xmas!
echo "\n";
echo 'N: '.$prm->getPromo('nyPromo')->getName(); // returns: Promotion for New Years!

这给了我Fatal error: Call to a member function setName() on a non-object in /var/www/test/index.php on line 11。 但为什么?不应该getPromo()给我回来的对象? 再次感谢..


感谢这里的好人,它现在有效。如果有人在这里通过相同或类似的问题,这里是最终的,有效的代码:

类:

class Promotion {
    private $__arr = array();
    public function addPromo($name) {
        $this->__arr[$name] = new Promo();
    }
    public function getPromo($name) {
        return $this->__arr[$name];
    }
}

class Promo {
    private $name;
    public function setName($name) {
        $this->name = $name;
    }
    public function getName() {
        return $this->name;
    }
}

测试文件:

require_once 'class.php';
error_reporting(E_ALL);

$prm = new Promotion();

$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');

$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
$prm->getPromo('nyPromo')->setName('Promotion for New Years!');

echo 'X: '.$prm->getPromo('xmasPromo')->getName(); // returns: Promotion for Xmas!
echo "\n";
echo 'N: '.$prm->getPromo('nyPromo')->getName(); // returns: Promotion for New Years!

2 个答案:

答案 0 :(得分:1)

方法链接非常简单,只需使用PHP语法的一个特定元素:

当函数返回一个对象时,您可以在该函数之后直接继续使用->

简写版可以是:

$bar = $foo->bar();
$baz = $bar->baz();
echo $baz;

$foo->bar()返回一个具有方法$bar的对象(baz()),该方法返回一些值($baz)。这可以用速记写成:

echo $foo->bar()->baz();

$foo->bar()仍然返回一个方法baz()的对象,因此您可以直接调用它而不将其分配给中间变量。也许这使得它更加明显:

echo ( $foo->bar() )->baz();

您在baz()返回时调用$foo->bar()方法。

$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');

因此,在上述情况下,您需要做的就是从setName返回一个方法为getPromo的对象。我认为getPromo应该返回Promo类的某些对象。如果Promo类有一个方法setName,那么您已经完成了设置。

答案 1 :(得分:1)

如果你想链接方法,你只需要像这样返回对象

class Chain {
    public function firstChain() {
         //do something
         return $this;
    }

    public function secondChain() {
          //do some stuff

          return $this;
    }

}

当你有一个类的实例时,你会这样做:

$obj = new Chain();

$obj->fistChain()->secondChain();