所以我有两个数组,
Array<GroundEnemy> groundEnemies;
Array<FlyingEnemy> flyingEnemies;
然后,我有使敌人为
的方法renderGroundEnemy(groundEnemies, delta);
renderFlyingEnemy(flyingEnemies, delta);
我将这些方法声明为
private void renderGroundEnemy(GroundEnemy enemies, delta){ ... }
private void renderFlyingEnemy(FlyingEnemy enemies, delta){ ... }
因为渲染飞行敌人的方法对于渲染地面敌人而言是相同的,所以我认为我只能重复使用相同的方法。现在,我很困惑如何设置该方法的参数类型。如何设置渲染方法的参数类型?我当时在想这样的事情,但我仍然不完全理解它,
private void renderEnemy(ArrayOfObjects enemies, delta){ ... }
一种惯用方法是为GroundEnemy
和FlyingEnemy
创建一个接口(或抽象类(。
例如:
public interface Enemy { ... }
public class GroundEnemy implements Enemy { ... }
public class FlyingEnemy implements Enemy { ... }
然后您只能使用Enemy
:
private void renderEnemy(Array<? extends Enemy> enemies, delta) { ... }
接口与抽象类的选择很重要:接口基本上说:
"我有这两件事:飞舞和公众,我想以相同的方式与他们互动。"
扩展抽象类意味着更多:
"我有这两件事:飞舞和公众,我想以相同的方式与他们互动。它们也非常相似。"
例如,如果FlyingEnemy
和GroundEnemy
都具有诸如stamina
或killed
之类的属性,或.hit()
或.heal()
之类的方法 - 那么将所有这些属性放入抽象类而不是重复实现(同一实现!(可能是有意义的!对于两种敌人类型。
请参阅此stackoverflow问题和以下答案,以很好地解释界面和抽象类概念之间的差异。
面向对象的编程的优点之一是您可以做到这一点。我假设地面和飞行元素的共同点不仅仅是渲染过程。惯例告诉您在这里做的是创建一个超级阶级的敌人,它具有飞行和地面敌人之间的相似之处。
然后飞行和地面敌人可以扩大敌人的阶级。
public class GroundEnemy extends Enemy { ... }
public class FlyingEnemy extends Enemy { ... }
现在,与两种类型的敌人共享的属性的任何方法都可以使用敌人作为参数类型。示例:
private void renderEnemy(Array<? extends Enemy> enemies, delta) { ... }
最好的方法是创建超级接口Enemy
并指定与GroudEnemy
和FlyingEnemy
相关的方法。代码:
public interface Enemy {
public void attack(int damage);
}
public interface GroundEnemy extends Enemy { ... }
public interface FlyingEnemy extends Enemy { ... }
现在GroudEnemy
和FlyingEnemy
都有方法attack
。