【问题标题】:How do I pass an argument to the parent constructor in oop PHP? [closed]如何在 oop PHP 中将参数传递给父构造函数? [关闭]
【发布时间】:2019-04-26 04:38:04
【问题描述】:

我正在尝试从一个基类实例化两个对象,并将一个参数从子类构造函数传递给父类构造函数。这似乎不起作用。就好像对象甚至不是父类的子对象一样。我不知道我做错了什么。

我已经尝试重新排列包含,不传递任何参数(这会导致错误,“需要一个参数”),以及其他修补都无济于事。

父类:

class SuperHero {
    private $health;
    private $name;
    private $isDead;

    public function __construct($name) {
        $this->name;
        $this->isDead = false;
    }

    // ...

    public function attack($opponent) { 
        echo $this->name.' attacks '.$opponent->name.'!<br>';
        $dmg = mt_rand(1, 10);
        $opponentHealth = determineHealth($opponent, $dmg);
        echo $opponent->name.' has '.$opponentHealth.' health left!<br>';
    }

    // ...

子类:

<?php
require_once('SuperHero.php');
class Batman extends SuperHero {

    public function __construct() {
        parent::__construct('Batman');
        $this->health = mt_rand(1, 1000);
    }

}

执行的脚本:

require_once('Batman.php');
require_once('Superman.php');

$h1 = new Batman;
$h2 = new Superman;

echo $h1->name.' is starting with '.$h1->health.' health!<br>';
echo $h2->name.' is starting with '.$h2->health.' health!<br>';

while($h1->getIsDead() == false && $h2->getIsDead() == false){    
    $h1->attack($h2);  
    $h2->attack($h1);
}

实际结果

is starting with 317 health!
Superman is starting with 300 health!
attacks !

预期结果

Batman is starting with 317 health!
Superman is starting with 300 health!
Batman attacks Superman!

【问题讨论】:

  • 您实际上从未在任何时候设置$this-&gt;name
  • 你在Superhero构造函数中忘记了$this-&gt;name = $name;
  • 另外,您正在尝试访问 $opponent-&gt;name$h1-&gt;healthnamehealth 是私有的。您需要 getter 才能访问这些属性。
  • 最后,你的整个设计都被窃听了。它使超人有可能击败蝙蝠侠;我们都知道这是不可能的。

标签: php oop inheritance


【解决方案1】:

你的父类的构造函数如下所示

public function __construct($name) {
    $this->name;
    $this->isDead = false;
}

$this-&gt;name; 单独什么都不做,它试图获取那个值。您需要通过执行

为其分配一个值
$this->name = $name;

那么,你所有的属性都是私有的,这意味着你不能通过$batman-&gt;name来访问它们。您需要为此实现一个 getter,$batman-&gt;getName()(对于您想要获取的每个属性)。如果它们是公开的,您可以通过 $batman-&gt;name 获取它们,但您也可以通过 $batman-&gt;name = 'Robin'; 覆盖它。最好使用 getter。

此外,determineHealth() 可能应该是类的方法并在 $opponent 对象上调用,而不是实际的函数。

class SuperHero {
    private $health;
    private $name;
    private $isDead;

    public function __construct($name, $health) {
        $this->name = $name;
        $this->health = $health;
        $this->isDead = false;
    }

    public function attack($opponent) { 
        $dmg = mt_rand(1, 10);
        echo $this->getName().' attacks '.$opponent->getName().' with '.$dmg." damage. ";
        $opponentHealth = $opponent->determineHealth($dmg);
        echo $opponent->getName().' has '.$opponentHealth." health left!<br />\n";
    }

    public function getName() {
        return $this->name;
    }

    public function getHealth() {
        return $this->health;
    }

    public function isDead() {
        return $this->isDead;
    }

    public function determineHealth($health) {
        $this->health -= $health;
        if ($this->health <= 0) {
            $this->health = 0;
            $this->isDead = true;
        }
        return $this->health;
    }
}

class Batman extends SuperHero {
    public function __construct() {
        $health = mt_rand(1, 1000);
        parent::__construct('Batman', $health);
    }
}

class Superman extends SuperHero {
    public function __construct() {
        $health = mt_rand(1, 1000);
        parent::__construct('Superman', $health);
    }
}

$h1 = new Batman;
$h2 = new Superman;


echo $h1->getName().' is starting with '.$h1->getHealth()." health!<br>\n";
echo $h2->getName().' is starting with '.$h2->getHealth()." health!<br>\n";

$h1->attack($h2);  
$h2->attack($h1);

输出:

Batman is starting with 445 health!<br>
Superman is starting with 229 health!<br>
Batman attacks Superman with 5 damage. Superman has 224 health left!<br />
Superman attacks Batman with 9 damage. Batman has 436 health left!<br />

【讨论】:

    【解决方案2】:

    超类的namehealth 成员在子类中不可用,因为它们是私有的。

    您应该将它们更改为 public 或者您应该创建公共 getter 和 setter 并使用它们。

    【讨论】:

      【解决方案3】:

      私有变量不能被继承。

          <?php
      class SuperHero {
          private $health;
          private $name;
          private $isDead;
      
          public function __construct($name) {
              $this->name = $name;
              $this->isDead = false;
          }
      
          public function name()
          {
              return $this->name;
          }
      
          public function attack($opponent) { 
              echo $this->name.' attacks '.$opponent->name.'!<br>';
              $dmg = mt_rand(1, 10);
              $opponentHealth = determineHealth($opponent, $dmg);
              echo $opponent->name.' has '.$opponentHealth.' health left!<br>';
          }
      }
      
      class Batman extends SuperHero {
      
          public function __construct() {
              parent::__construct('Batman');
              $this->health = mt_rand(1, 1000);
          }
      
      }
      class Superman extends SuperHero {
      
          public function __construct() {
              parent::__construct('Superman');
              $this->health = mt_rand(1, 1000);
          }
      
      }
      
      $h1 = new Batman;
      $h2 = new Superman;
      
      echo $h1->name().' is starting with '.$h1->health.' health!<br>';
      echo $h2->name().' is starting with '.$h2->health.' health!<br>';
      
      while($h1->getIsDead == false && $h2->getIsDead == false){    
          $h1->attack($h2);  
          $h2->attack($h1);
      }
      
      ?>
      

      在父类中 function name() 将返回从 parent::__construct('Name') 传递的名称。

      输出

      Batman is starting with 327 health!
      Superman is starting with 842 health!
      Batman attacks Superman!
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-13
        • 2020-05-20
        • 2011-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多