是否可以分类演员?

时间:2013-01-24 01:16:58

标签: php

我是一个普通类继承的新手,但我对php更加困惑。

我想要以下内容:

class Base
{
     //some fields and shared methods...
}

class Node
{
     private $children = array();

     public function getChildren()
     {
          ...
     }

     public function addChild($item)
     {
         $children[] = $item;
     }

     public function sum()
     {
     }
}

I want $item to be either another Node or a Leaf:

class Leaf extends Base
{
     private $value;

     public getValue()
     {
     }

     public setValue($someFloatNumber)
     {
          $this->value = $someFloatNumber;
     }
} 

对于公共金额(),我想要类似的东西:

$sum = 0;

foreach ($children as $child)
{
    switch(gettype($child))
    {
        case "Node":
           $sum+= ((Node) $child)->sum();
           break;
        case "Leaf":
           $sum+= ((Leaf) $child)->getValue();
           break;
    }
}

return $sum;

不确定如何进行演员表演。数组也会存储添加的$ item的类型吗?

2 个答案:

答案 0 :(得分:1)

这不是合适的OOP。试试这个:

将方法sum添加到Base(如果您不想实现,则为摘要)。为sum实现相同的方法Leaf,只需返回getValue。然后你可以简单地在两种类型上调用sum,因此不需要大小写,或者知道它的类型等等:

foreach ($children as $child) {
    $sum += $child->sum();
}

这称为多态,它是面向对象编程的基本概念之一。

要回答您的问题,您可以在Netbeans和Zend Studio(以及可能还有其他编辑)的本地提示类型:

/* @var $varName Type_Name */

答案 1 :(得分:1)

你问的是提示,但是在你的代码中,你实际上是在尝试进行演员。这不是必要的,也不可能以这种方式。

提示示例:

private function __construct(Base $node) {}

这确保您只能传递Base的实例或继承类到函数。

或者,如果在IDE中工作很重要,您可以这样做:

$something = $child->someMethod(); /* @var $child Base */

这将确保您的IDE(和其他软件)知道$child属于Base类型。

而不是投射你可以像这样使用is_a

if (is_a($child, 'Node') {}
else (is_a($child, 'Leaf') {}

但说实话,您似乎应该重构代码。我认为叶子与节点有任何不同并不是一个好主意。叶子只是一个没有任何子节点的节点,您可以随时使用$node->hasChildren()进行测试,如果需要,甚至可以设置和取消设置叶子标记。