PHP类,继承,实现

Joh*_*ohn 2 php

我在看我应该使用多个类来进行游戏吗? - 罗伯特皮特的回答.

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()
    {

    }



}
Run Code Online (Sandbox Code Playgroud)

关于"人类",我或许要实施"武器"而不是柯尔特,然后在"狙击手"上初始化正确的武器类?

class Sniper extends Human
{
public $weapon;

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


$this->weapon->fire();


}
Run Code Online (Sandbox Code Playgroud)

或类似的东西?我很困惑它是如何工作的..

EXAMPLE 1

class A {
public $class;

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

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

class B {
public function hello() {
echo 'hi';
}
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*in. 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);
Run Code Online (Sandbox Code Playgroud)

演示


Mat*_*lin 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 {}
Run Code Online (Sandbox Code Playgroud)

我现在解释一下:

iWeapon

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

iAttacker/iAttackable

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

关于接口

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

希望这可以帮助 :)


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

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());
        }
    }

}
Run Code Online (Sandbox Code Playgroud)