【问题标题】:PHP class extends not working why and is this how to correctly extend a class?PHP类扩展为什么不起作用,这是如何正确扩展一个类?
【发布时间】:2011-07-17 00:58:04
【问题描述】:

您好,我正在尝试使用面向对象编程来了解 inherteince 在 PHP 中的工作原理。主类是Computer,继承类是Mouse。我正在用鼠标类扩展计算机类。我在每个类中都使用 __construct,当我启动类时,我首先使用 pc 类型,如果它之后有鼠标。出于某种原因,计算机返回 null?这是为什么?

class Computer {
    protected $type = 'null';

    public function __construct($type) {
        $this->type = $type;
    }
    public function computertype() {
        $this->type = strtoupper($this->type);
        return $this->type;
    }

}

class Mouse extends Computer {
    protected $hasmouse = 'null';
    public function __construct($hasmouse){
         $this->hasmouse = $hasmouse;

    }
    public function computermouse() {
         if($this->hasmouse == 'Y') {
             return 'This Computer has a mouse';
         }
    }

}

$pc = new Computer('PC', 'Y');
echo $pc->computertype;
echo $pc->computermouse;

【问题讨论】:

  • 不是直接相关的答案,但如果您的计算机对象具有鼠标属性(鼠标类型的对象)会更有意义
  • @Erik I 这个评论对我帮助最大,让我重新思考父类的构建。

标签: php oop inheritance extend


【解决方案1】:

继承不是这样工作的。

继承(又名extend)允许您根据父类的属性和方法扩展子类。

考虑以下示例:

class Peripheral {
  private $connectionType;
  private $isConnected = false;

  function __construct($connectionType) {
    $this->connectionType = $connectionType;
  }

  function getConnectionType() {
    return $this->connectionType;
  }

  function connect() {
    $this->isConnected = true;
  }

  function disconnect() {
    $this->isConnected = false;
  } 

  function isConnected() {
    return $this->isConnected;
  }
}

您现在可以扩展 Peripheral 类,因为 Mouse 是外设。

class Mouse extends Peripheral {
  private $numOfButtons;

  function __construct($connectionType, $numberOfButtons) {
    parent::__construct($connectionType);
    $this->numOfButtons = $numOfButtons;
  }

  function getNumOfButtons() {
    return $this->numOfButtons;
  }

  function leftClick() {
    if($this->isConnected())
      echo "Click!";
  }

  function rightClick() {
    if($this->isConnected())
      echo "RightClick!";
  }
}

现在,因为MousePeripheral 的子类,所以Peripheral 中定义的所有方法都可以在Mouse 中访问,但反之则不行...

所以虽然我可以这样做:

$mouse = new Mouse('USB', 2);
echo $mouse->getConnectionType(); // USB
$mouse->connect();
$mouse->leftClick();

我无法执行以下操作:

$perip = new Peripheral('USB');
echo $perip->getConnectionType(); // USB
$perip->connect();
$perip->leftClick(); // ERROR: leftClick not defined.

【讨论】:

  • 你能告诉我如何创建和实例化这些类吗?
  • 写得好,清晰,应该顶上!
【解决方案2】:

它并不像那样工作。如果你创建一个new Computer,你就会得到。您想创建一个 new Mouse() 类型的计算机(尽管这对我来说似乎很奇怪)。

父对象(计算机)不知道它有一个子对象(鼠标)。这是因为一个父类可以有多个子类。

一般情况下,您会拥有类似苹果扩展计算机或戴尔扩展计算机之类的东西

$a = new apple();
$b = new dell();

他们都有在计算机中定义的可用方法,以及他们自己的方法。

此外,当您覆盖 __construct 之类的方法时,如果您希望它执行,则必须显式调用父构造函数(或方法),例如:

class computer {
   function __construct() { do stuff }
}

class apple extends computer {
   function __construct() {
        parent::__construct();
        ... do stuff ...
    }
}

只有你实例化的类的方法被执行。如果它无法在子类中找到该方法,则它会在链中查找方法。 IE。如果computer 类有'movemouse' 而你的子类没有它会在父类中执行movemouse 类。

【讨论】:

    【解决方案3】:

    代替:

    $pc = new Computer('PC', 'Y');

    你想要的

    $mouse = new Mouse('PC', 'Y');

    目前你有它,所以鼠标扩展计算机。

    【讨论】:

    • 好的,我已经把它们颠倒了,但是由于 strtoupper 和它旁边的“PCTYPE”,计算机仍然返回 null 但大写?
    • 我的答案解决了为什么你有一个空值。两个构造函数都没有运行。
    • 继承要记住的一点是“is-a”概念。在您的示例代码中,鼠标是计算机。因此,这意味着鼠标可以做计算机可以做的所有事情,可能会增加一些功能或以不同的方式。您似乎想要一种“具有”关系,这种关系通常不是继承,而是组合。计算机有鼠标,因此计算机的构造函数可以采用鼠标或鼠标对象的设置器。
    • @Myles,同意了。我打算进一步详细说明,但@Erik 总结得很好。
    【解决方案4】:

    您当前的鼠标构造函数将只接受一个值。如果您希望 Mouse 同时接受 $type 和 $hasmouse,那么您需要接受两个值。

    class Mouse extends Computer {
        protected $hasmouse = 'null';
        public function __construct($type, $hasmouse) {
            parent::__construct($type);
            $this->hasmouse = $hasmouse;
        }
        public function computermouse() {
             if($this->hasmouse == 'Y') {
                 return 'This Computer has a mouse';
             }
        }
    }
    
    $pc = new Mouse('PC', 'Y');
    

    我还建议使用布尔值 (true/false) 而不是 'Y'

    【讨论】:

    • 为什么建议使用布尔变量?
    • 这样想。陈述:它有一只老鼠?真假。这也使得它更容易在条件句中使用:if($this->hasmouse)。最后,因为它是一个标准约定。有一天,除了你之外,有人会维护你的软件——如果你用“Y”和“N”来判断真/假,希望他们不知道你住在哪里。
    猜你喜欢
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多