Java中抽象类的不同实现

时间:2014-11-06 14:55:24

标签: java inheritance abstract-class subclass superclass

我正在构建一个迷宫游戏,玩家必须在追逐他的敌人的迷宫中导航。

我想知道用“Zombie”和“Vampire”子类实现Enemy类的最佳方法是什么。目前,除了颜色外,两个类几乎完全相同。运动策略是相同的,但这可能在未来发生变化。另外,我希望允许扩展性,即如果客户想要添加更多具有不同移动策略的敌人而不改变现有代码库,则可以这样做。

我正在寻找不同的方法:

  1. 只需使用一个Enemy类,它在其构造函数中包含一个字符串,并根据是否传入“Zombie”或“Vampire”来决定使用“Enemy”的颜色。但是这不允许有不同的运动策略,如果添加了许多其他敌人,将会建立条件分支。

  2. 摘要使用抽象方法move()getColor()的敌人类,这允许每个类定义自己的移动策略并保持对其颜色的引用。然而,如果敌人的颜色可能不同,那么这有点过分。敌人运动在我的实施中都是一样的,但展示可扩展性的潜力总是有利的。

4 个答案:

答案 0 :(得分:1)

我会为游戏的每个部分创建一个界面,例如移动,攻击或npc(ness)。创建一个实现所有接口的不死敌人类,然后用吸血鬼和僵尸类扩展它,以覆盖颜色属性检索方法。我根本不会使用抽象类。

答案 1 :(得分:0)

我会选择1)

<强>原因

据我了解OPs问题,每个敌人都有相同的方法和属性。只是他们的运动策略不同。所以我会生成一个抽象类MovementStrategy(正如名称已经暗示你应该考虑策略模式)。只需将类型为MovementStrategy的成员添加到Enemy - 类,并将nextMove方法委托给此对象。所以每个僵尸也可以有其他策略(简单/硬模式)。

您还可以考虑此课程中的基本行为。 Enemy类的层次结构不是一个很好的选择(IMO),这是他们唯一不同的东西。

但是

这仅适用于要求不会发生剧烈变化的情况!

修改

正如评论中暗示的那样:在这种情况下,你不能仅使用String构造对象。

修改2

对于这个变体来说,没有什么能阻止你继承Enemy,但不是因为它们的策略不同。 我不喜欢的方式,例如aleksamarkoni“将”实现选项2,他为超类型中的变量定义常量。因此,你首先要删除有关常量变量的观点(类不是对象!)。 如果另一个僵尸有不同的绿色阴影怎么办?你会用另一种阴影生成第三类僵尸(LighterGreenZombie类)吗?所以基本上僵尸和吸血鬼有什么区别?除了颜色,名称和运动策略之外什么都没有!有了这些要求,解除运动策略就会使敌人完全变得毫无意义,而且更加干净!

答案 2 :(得分:0)

第二个选项比第一个选项更好,特别是如果你要包含新类型的敌人。如果你对这两种类型的敌人有相同的动作,你可以将你的移动代码放在抽象的敌人类中,这样僵尸和吸血鬼就可以分享它。这是我的方式。

public abstract class Enemy {
    // every enemy has the color, so you can put it here
    protected String color;
    public void move() {
        // your basic move strategy here, this will include both the zombie and the vampire
    }
}

public class Zombie extends Enemy{

    // default constructor lets say zombies are black
    public Zombie() {
        color = "black";
    }

    // or you can have some color added throught constructor
    public Zombie(String color) {
        this.color = color;
    }

    // you dont have to override move function, because its the same as Enemy one
}

public class Vampire extends Enemy {

    // default constructor lets say vampires are red
    public Zombie() {
        color = "red";
    }

    // or you can have some color added throught constructor
    public Zombie(String color) {
        this.color = color;
    }

    // you dont have to override move function, because its the same as Enemy one
}

public class NewEnemy extends Enemy {

    // default constructor lets say new enemy is green
    public Zombie() {
        color = "green";
    }

    // or you can have some color added throught constructor
    public Zombie(String color) {
        this.color = color;
    }

    // lets say new enemy has diffrent move strategy
    @Override 
    public void move() {
        // new move strategy, only for the new enemy
    } 
}

答案 3 :(得分:0)

第二种选择是迄今为止更好的选择,看到将来如果你想制造更多具有相似功能的敌人,你可以再次扩展抽象类。

此外,如果你想为每个敌人添加独特的元素,你可以改变相应的子类,而不是搞乱主要的Enemy类。

最后,如果你想在主要抽象中为每个敌人添加一个新的抽象特征/方法,那么Enemy类将迫使你在每个子类中实现它,确保你在整个板上做出一致的改变。