PHP类扩展不起作用,为什么,这是如何正确扩展类?

PHP class extends not working why and is this how to correctly extend a class?

提问人:Aaron 提问时间:3/17/2011 更新时间:3/17/2011 访问量:5979

问:

嗨,所以我正在尝试使用面向对象编程来了解 inherteince 如何在 PHP 中工作。主类是 Computer,继承的类是 Mouse。我正在使用 mouse 类扩展 Computer 类。我在每个类中使用__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;
php oop 继承 扩展

评论

2赞 Erik 3/17/2011
这不是一个直接相关的答案,但如果您的计算机对象具有 Mouse 属性,则更有意义,该属性是 Mouse 类型的对象
0赞 Aaron 3/17/2011
@Erik我这个评论对我帮助最大,让我重新思考父类的构造。

答:

2赞 RDL 3/17/2011 #1

而不是:

$pc = 新计算机('PC', 'Y');

你想要

$mouse = 新鼠标('PC', 'Y');

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

评论

0赞 Aaron 3/17/2011
好的,我已经反转了它们,但计算机仍然返回 null,但由于 strtoupper 而大写,然后是旁边的“PCTYPE”?
0赞 Erik 3/17/2011
我的答案解决了为什么你有一个空值。两个构造函数均未运行。
3赞 Myles 3/17/2011
继承要记住的一件事是“是”概念。在示例代码中,鼠标是一台计算机。因此,这意味着鼠标可以做计算机可以做的所有事情,可能加上一些功能或以不同的方式。你似乎想要一种“有”的关系,这种关系通常不是继承,而是组成。计算机有一个鼠标,因此计算机的构造函数可以采用鼠标或具有 Mouse 对象的 setter。
0赞 RDL 3/17/2011
@Myles,同意了。我打算进一步详细说明,但@Erik很好地总结了它。
3赞 Erik 3/17/2011 #2

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

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

一般来说,你会有一台苹果扩展电脑,或者戴尔电脑,然后你就会有

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

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

此外,当您重写一个方法时,如果希望它执行,则必须显式调用父构造函数(或方法),例如:__construct

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

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

仅执行实例化类的方法。如果它在子类中找不到方法,则它会在链中查找方法。即。如果类有“movemouse”,而你的子类没有,它将在父类中执行该类。computermovemouse

4赞 Andrew Moore 3/17/2011 #3

这不是继承的工作方式。

继承(又名)允许您根据子类的父类的属性和方法扩展子类。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;
  }
}

您现在可以扩展该类,因为 a 是 Peripheral。PeripheralMouse

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!";
  }
}

现在,因为是 的子类,所以 中定义的所有方法都可以在 中访问,但不能反过来访问......MousePeripheralPeripheralMouse

因此,虽然我可以做到这一点:

$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.

评论

0赞 Aaron 3/17/2011
你能告诉我如何创建和实例这些类吗?
0赞 brasofilo 12/23/2012
写得很棒,晶莹剔透,应该被点到最高!
1赞 Nick Clark 3/17/2011 #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”

评论

0赞 Aaron 3/17/2011
为什么建议使用布尔变量?
2赞 Erik 3/17/2011
这样想吧。声明:它有鼠标吗?真/假。这也使其更易于在条件语中使用:。最后,因为这是一个标准约定。总有一天,除了你之外,还会有人维护你的软件——如果你用“Y”和“N”来表示真/假,希望他们不知道你住在哪里。if($this->hasmouse)