我在看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';
}
}
答案 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);
答案 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()函数。