PHP类,继承,实现

时间:2011-11-29 15:09:33

标签: php

我在看Should I use multiple classes for game? - 罗伯特皮特的回答。

interface Weapons {

    public function Fire();

}

class Colt implements Weapons {

    function Fire() {
        echo 'Fire!';
    }

}

abstract class Human implements Colt
{

}

class Sniper extends Human
{
    public function __construct()
    {

    }



}

关于“人类”我是否可能实施“武器”而不是柯尔特,然后在“狙击手”上初始化右武器类?

class Sniper extends Human
{
public $weapon;

    public function __construct($weapon)
    {
    $this->weapon = new $weapon;  
    }


$this->weapon->fire();


}

或类似的东西?我对它是如何工作感到困惑。

EXAMPLE 1

class A {
public $class;

__construct() {
$this->class = new $class;
}

hello() {
$this->class->hello();
}
}

class B {
public function hello() {
echo 'hi';
}
}

3 个答案:

答案 0 :(得分:5)

这取决于你,你将如何设计你的课程。

如果我是游戏程序员,我可能会使用类似的东西(这是一个有效的迷你游戏!)

<?php
class Fight {
     public $weapon;
     public $name;
     public function __construct($weapon, $name)
     {
        $this->name = $name;
        $this->weapon = new $weapon;
     }
     public function fire($person) {
         $this->weapon->fire($person);
     }
     public function changeWeapon($weapon) {
        $this->weapon = new $weapon;
     }
}

class Sniper extends Fight {   }
class Terrorist extends Fight {   }

class MauserSniper {
     function fire($person) {
         echo "Firing $person->name! Miss! Your rifle is damaged<br />";
     }
}

class AK47 {
     function fire($person) {
         echo "Firing $person->name! Hit with AK47!<br />";
     }
}


class SteyrSSG {
     function fire($person) {
         echo "Firing $person->name! Hit!<br />";
     }
}

$sniper1 = new Sniper("MauserSniper", "Martin");
$sniper2 = new Sniper("SteyrSSG", "Daniel");
$terrorist = new Terrorist("AK47", "Mike");
$sniper1->fire($sniper2); //we'll miss this one.
$sniper1->changeWeapon("SteyrSSG");
$sniper1->fire($sniper2); //hit!
$terrorist->fire($sniper1);

demo

答案 1 :(得分:5)

在我这边,我会使用这些类:

Interface iWeapon {}
Interface iAttacker {}
Interface iAttackable {}

Class Human Implements iAttacker, iAttackable {}
Class RangedWeapon Implements iWeapon {}
Class Colt extends RangedWeapon {}
Class M4AA extends RangedWeapon {}
Class Sniper extends RangedWeapon {}
Class Shotgun extends RangedWeapon {}

让我现在解释一下:

<强> iWeapon

描述武器,不同的getter,setter和一些动作,如DoDamage()或GetRandomAttackDamage()。它如你所愿。此界面允许您定义武器的基础知识。你可以将它应用于Weapon类或任何其他派生它的类,但我会将它保存到至少一个基本类。接口的目标是强制所有武器添加相同的行为,它有攻击伤害,射程,可能是收费? (弹药)

iAttacker / iAttackable

描述可以攻击或受到攻击的内容。这些接口通常会提供一些功能来确定攻击能力(被攻击,固定,禁用?)或被攻击(不可见,无敌?)并提供攻击其他实现的功能。人类或任何其他生物将实施这些,说,嘿,我可以攻击并受到攻击。这个界面还会提供吸气剂和制定者来控制这些生物携带的武器,也许是为了防止它们受到伤害?

关于界面

永远记住,类代表了相对具体的东西。如果您将您的班级命名为“攻击者”或“目标”,您可能会忽略课程的重点。表示有形事物的类和对象。另一方面,接口表示类可能采取的操作或角色。他们只指定一个人可以做什么,他们不提供实现本身,他们告诉该对象将实现什么,从而声明他们可以做什么。

希望这会有所帮助:)


关于属性的正确实现,我建议:

class Player implements iAttacker, iAttackable {
    protected $playerClass;
    protected $race;
    protected $weapon;
    protected $armor;

    public function setClass(playerClass $class){
         $this->playerClass = $class;
    }
    public function getClass(){
         return $this->playerClass;
    }

    public function setRace(race $race){
         $this->race = $race;
    }
    public function getRace(){
         return $this->race;
    }

    public function setWeapon(damagingGear $weapon){
         $this->weapon = $weapon;
    }
    public function getWeapon(){
         return $this->weapon;
    }

    public function setArmor(protectiveGear $armor){
         $this->armor = $armor;
    }
    public function getArmor(){
         return $this->armor;
    }

    public function attack(iAttackable $target){

        //Check we can attack
        if(!$this->canAttack()){ //Check we are not immobilized or disabled
            throw new CannotAttackException($this->getNonAttackingReason());
        }elseif(!$this->weapon->canFire()){
            throw new CannotAttackException($this->weapon->getNonFireableReason());
        }

        //We can attack, roll the damage
        if($target->isAttackable()){
            $target->sufferDamage($this->weapon->rollDamage()+$this->race->getRangedDamageBonus());
        }else{
            thrown new CannotBeAttackedException($target->getNonAttackableReason());
        }
    }

}

答案 2 :(得分:2)

我会避免让Human类实现与武器有关的任何事情。实现定义了类必须定义的方法,但不处理类的属性。

  

对象接口允许您创建指定哪些代码   类必须实现的方法,而不必定义这些方法   处理方法。   (PHP Documentation: Object Interfaces

Class Human {}

Class Sniper extends Human{
 public $weapon
}

Interface Weapons {
  public function fire() 
}

Class Colt implements Weapons {}
Class Bazooka implements Weapons {}

因此,狙击手是人类(但具有$ weapon属性),而Colt,Bazooka等都实现了Weapons界面(强制他们定义fire()函数。