java打怪兽_java当中怪物类如何引用武器类打怪兽类

展开全部

这是个挺有趣的问题,我们可以一起来分析下:

1.这里面只有两32313133353236313431303231363533e59b9ee7ad9431333335343961个类,武器类和怪兽类;而动作只有一个,打。

2.面向对象的思想是为类分配职责,那么打这个动作到底分配给谁?

很明显应该分配给怪兽类,因为打这个动作涉及的大部分数据都是怪兽类包含的,从常识上来讲分配给武器类感觉怪怪的...

3.从上面可以想象到会出现这样的情况monster.hit(otherMonster),这里monster是打,otherMonster是被打。hit方法里面需要将otherMonster的信息获取出来,然后计算打的过程...这样会把otherMonster的数据封装破坏掉,如果扩展otherMonster,显然你必需要在hit方法里判断otherMonster是哪种类型。但是monster.hit(otherMonster)又是符合对象的思维的。那么问题出在哪里?

问题出在打是一个动词,打这个方法分配给了一个对象,但作用的是另一个对象,因此而破坏了数据封装。如果打分配给一个对象,同时作用的是这个对象,那么问题就解决了。

怎样把打分配给一个对象,同时作用的是这个对象呢?答案是把打转换成被打,于是就成了otherMonster.hit(),在monster需要去打otherMonster时,调用otherMonster.hit()就可以了。

4.武器类还没有被引入进来,明显武器不会自动攻击,他必须装备在monster上,我们可以把weapon作为monster的成员。

5.武器类可以被使用在打这个动作上,于是我们为hit方法增加武器参数,于是就变成otherMonster.hit(weapon),这个方法是在monster内部调用的,weapon也是monster的成员,没有破坏封装性。

6.至此,你提的这个问题就是这样了...class Monster{

private Weapon weapon;

public void hit(Weapon weapon){

//dosometing.

}

public Weapon getWeapon(){

return weapon;

}

public void setWeapon(Weapon weapon){

this.weapon = weapon;

}

}

是不是感觉怪怪的...我们可以继续来探讨这个问题:

为什么感觉怪怪的?是因为这个问题太简化了,简化到我们并不知道Monster被打之后到底发生什么。

感觉这个很像个游戏,大部分游戏都是基于hitpoint(血量)的,为了使这个问题带感一些,我们给Monster一个int类型的hitPoint。

同时给武器类赋予一个attackPoint,在Monster被打的时候扣除attackPoint数量的hitPoint。

那么问题来了,hit方法里需要获取Weapon中的attackPoint,这又会把Weapon的数据封装破坏掉...

为此我们需要给Monster一个直接扣除hitPoint的方法damage(int attackPoint),让Weapon能够调用damage方法把自身的attackPoint传递进来。

Weapon本身我们可以分配一个attack(Monster monster)方法来给Monster把自身传递进来,于是程序就变成了:class Monster{

private Weapon weapon;

private int hitPoint;

public void hit(Weapon weapon){

weapon.attack(this);

}

public void damage(int attackPoint){

this.hitPoint -= attackPoint;

}

public Weapon getWeapon(){

return weapon;

}

public void setWeapon(Weapon weapon){

this.weapon = weapon;

}

}

class Weapon{

private int attackPoint;

public void attack(Monster monster){

monster.damage(attackPoint);

}

}

也许有人会问,hit里面调用weapon.attack,attack里面又调用monster.damage,那还不如在hit里直接获取weapon的attackPoint,然后直接扣除hitPoint。

为什么要这么麻烦呢?实际上这里Weapon是一个策略(Strategy模式),由策略来决定对对象到底采取什么样的作用。这里感觉麻烦也是因为问题太简单了。

再带感一点,我们参考网游的做法,Monster本身有一定的躲避和格挡率,同时某些Weapon可能会有暴击率:

此时我们需要在hit方法里先计算是否躲避或者格挡,如果都不成功,才调用weapon.attack(this).在attack方法里,需要先计算是否暴击,如果暴击,则把attackPoint乘以2。于是又变成了class Monster{

private Weapon weapon;

private int hitPoint;

private int dodge;//100%比例

private int block;//100%比例

public void hit(Weapon weapon){

if (isDodge()){

return;

}

if (isBlock){

return;

}

weapon.attack(this);

}

public void damage(int attackPoint){

this.hitPoint -= attackPoint;

}

public boolean isDodge(){

//COMPUTE IS DODGE?

}

public boolean isBlock(){

//COMPUTE IS BLOCK?

}

public Weapon getWeapon(){

return weapon;

}

public void setWeapon(Weapon weapon){

this.weapon = weapon;

}

}

class Weapon{

private int attackPoint;

private int critical;//100%比例

public void attack(Monster monster){

int actualAttackPoint = isCritical()?attackPoint*2:attackPoint;

monster.damage(actualAttackPoint);

}

public boolean isCritical(){

//COMPUTE IS CRITICAL

}

}

这样就不觉得麻烦了...

最后应该把monster抽象成接口,因为可能不只是monster可以被武器打哦

你还可以后面再加入怎么判断Monster挂了,通过观察者模式来通知打人者,还有其他各种各样带感的东西。

祝你好运!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值