PHP上的类实例?

时间:2012-06-08 19:29:37

标签: php

我不知道它叫什么,我相信它是实例。

假设我们有一个“怪物”类。此类应包含“运行状况”值。在类创建时将其设置为“5”。它还应包含每个怪物的唯一ID值。

我想到这样的事情:

$monster_1 = new Monster(); //sets monster ID to 1
$monster_2 = new Monster(); //sets monster ID to 2
$monster_3 = new Monster(); //sets monster ID to 3

所以,假设我想计算所有怪物的总HP值。

$totalHp = $monster_1->getHp() + $monster_2->getHp() + $monster_3->getHp();

它也会起作用,但是如果我添加一个名为$monster_4的新怪物会怎样。我必须手动将它添加到$ totalHp计算中。

我可以创建一个数组而不是$monster个变量,并使用foreach计算$ totalHp - 但它看起来很奇怪......

我不知道它是如何用其他语言完成的。

还有其他方法可以实现这个目标吗?

聚苯乙烯。我正试图让“http://www.scirra.com/demos/ghosttutorial/”游戏背后的逻辑。你创建了一个Monster类,每个Monster都使用这个类作为实例。我的解决方案肯定会奏效,但我不确定这是否是一种愚蠢的方式来实现这一目标。

10 个答案:

答案 0 :(得分:3)

创建一个包含一组Monsters的助手类,可能是MonsterTeam类;

class Monster {
     ...
}

class MonsterTeam {
    private $_monsters = [];

    public function addMonster(Monster &$monster) {
        array_push($this->_monsters, $monster);
    }

    public function getTotalHp() {
        $hp = 0;

        foreach ($this->_monsters as $monster) {
            $hp += $monster->getHp();
        }

        return $hp;
    }
}


$team = new MonsterTeam();

$monsterA = new Monster();
$team->addMonster($monsterA);

$monsterB = new Monster();
$team->addMonster($monsterB);

echo "Total HP: " . $team->getTotalHp();

答案 1 :(得分:2)

首先,它们被称为对象实例,如面向对象的编程?

其次,没有什么能阻止你创造怪物的数组(看起来并不奇怪):

$monsters = array(
    new Monster(),
    new Monster(),
    new Monster(),
    new Monster()
);

foreach($monsters as $monster) {
    $totalHP += $monster->hp;
}

关于唯一ID,应该由MonsterFactory负责,这意味着,怪物应该分配一个ID,它不应该将其分配给自己< / strong>,而ID应该分配给它。创建怪物时有类似的事情:

new Monster(4); //ID is 4

谁跟踪它?别人,不是怪物。

答案 2 :(得分:1)

您可以使用充当Monsters容器的对象,并使用它来跟踪:

class MonsterContainer
{
    private $monsters = array();

    public function __construct()
    {
       // do stuff   
    }   

    public function addMonster(Monster $monster)
    {
        $this->monsters[] = $monster;   
    }

    public function totalMonstersHP()
    {
        $hp = 0;
        foreach ($this->monsters as $monster)
        {
            $hp += $monster->getHp()
        }
        return $hp;
    }
}

$monster_1 = new Monster(); 
$monster_2 = new Monster(); 
$monster_3 = new Monster(); 

$container = new MonsterContainer();
$container->addMonster(monster_1);
$container->addMonster(monster_2);
$container->addMonster(monster_3);
echo $container->totalMonstersHP();

答案 3 :(得分:1)

你可以像这样创建一个$monsters数组:

$monsters = array();

然后每次你想添加怪物时,你都会这样做:

$monsters[] = new Monster();

然后你可以循环遍历你的数组以获得如下所示的总命中率:

$totalHP = 0;
foreach($monsters as $monster) {
    $totalHP += $monster->getHp();
}

在该循环之后,$totalHP将包含阵列中所有怪物的总生命值。

答案 4 :(得分:1)

您可以创建一个收集工厂;它将负责创造新的怪物。将两个类融合在一起通常不是我的事,但我喜欢这样的事实:我可以通过这种方式使构造函数变为私有:)

它使用两个静态变量(我认为是美化的全局变量),一个用于怪物id,另一个用于怪物集合,使用SplObjectStorage

需要迭代所有怪物的方法使用each()方法,因此您可以在类之外定义所需的任何逻辑。

class Monster
{
  private $id;
  public $health;

  private static $instances;
  private static $nextid = 1;

  // private constructor
  private function __construct($id)
  {
    $this->id = $id;
    $this->health = 5;
  }

  public static function create()
  {
    if (!self::$instances) {
      self::$instances = new SplObjectStorage;
    }
    $o = new self(self::$nextid++);
    self::$instances->attach($o);

    return $o;
  }

  public static function remove($o)
  {
    if (!self::$instances) { return; }
    self::$instances->detach($o);
  }

  // iterate over all objects
  public static function each($cb)
  {
    if (!self::$instances) { return; }
    foreach (self::$instances as $o) {
      $cb($o);
    }
  }
}

小用法示例

$m1 = Monster::create();
$m2 = Monster::create();

$total_health = 0;
Monster::each(function(Monster $m) use (&$total_health) {
  $total_health += $m->health;
});
echo "Total health: $total_health\n";

答案 5 :(得分:0)

我是第二个alexn,使用数组来存储类实例(是的,这是正确的术语)非常好。

然后,您可以使用foreach来计算总HP。

答案 6 :(得分:0)

创建MonstersCollection类,其中包含方法getNewMonster()getTotalHP()

伪代码:

class MonstersCollection
{
   private $Monsters;

   public function getNewMonster()
   {
       $Monster=new Monster();
       $this->monsters[]=$Monster;
       return $Monster;
    }

   //and you know how to write method to get total HP :)
}

答案 7 :(得分:-1)

类跟踪其实例是很常见的。

class Monster {
    private $monsters = array();
    public function __construct() {
       self::monsters[] = $this;
    }

    public  function __destruct() {
        array_splice(self::monsters, array_search($this, self::monsters), 1 );
    }

    public static function getTotalHp() {
         $total = 0;
         foreach(self::monsters as $monster) {
            $total += $monster->getHp();
         }
         return $total;
    }    
}

答案 8 :(得分:-2)

也许你可以在同一个Monster类中创建一个新类或函数 在构造函数中调用,每次创建类 它调用一个增加的全局变量。

答案 9 :(得分:-2)

您可以创建可在Monster实例化中自动更新集中对象中的totalHp属性的观察者模式。

但是在Monster课程中,更快/更简单的方法就是这样:

class Monster {

   ...
   private $hp = 5;
   private static $totalHp = 0;
   ...

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

   public function __construct(...) {
       ...
       self::totalHp += $this->getHp();
       ...
   }

   public function __destruct(...) {
       ...
       self::totalHp -= $this->getHp();
       ...
   }

   ...

   public static function getTotalHp() {
       return self::totalHp;
   }

   /**
    * Provide negative number to reduce HP or positive to increase HP.
    */
   public function alterHp($hp) {
       $this->hp += $hp;
       self::totalHp += $hp;
   }
}

然后,要获取当前的totalHp值,您必须在客户端代码中执行以下操作:

$totalHp = Monster::getTotalHp();