如何在没有getClass()的情况下区分Java中的类似对象?

时间:2015-10-26 23:41:11

标签: java object design-patterns identification

我正在制作一个简单的Java游戏,我认为我有一个设计问题。我有一个抽象类Unit,它具有所有单位的行为(如move(),attack(),getHealth(),...)。然后我从Unit扩展了三个类:Archer,Lancer,Rider。其中每一个都只有一个构造函数来区分它们,因为它们的行为完全相同,但具有不同的统计数据。

public class Archer extends Unit {    
    public Archer(World world, Location location, Player owner) {
        super(new Attack(1, 6, 1), new Defense(1, 4, 2), 10, 4, location, owner);
    }
}

public class Lancer extends Unit {    
    public Lancer(World world, Location location, Player owner){
        super(new Attack(2, 2, 5), new Defense(3,2,3), 15, 5, location, owner);
    }
}

public class Rider extends Unit{    
    public Rider(World world, Location location, Player owner) {
        super(new Attack(3, 2, 4), new Defense(2,4,1), 15, 7, location, owner);
    }
}

现在出现了问题。我希望能够打印具有不同精灵的单元,因此我制作了具有每个精灵的ArcherUI,LancerUI和RiderUI类。但是如何告诉程序打印例如Archer?

解决方案可能是为每个单元做一个getClass(),但它不是一个好的,因为我想要一个好的面向对象的设计。

我想到的另一个选择是为单位添加一个名称:

public class Archer extends Unit {  
    String name = "archer";
    public Archer(World world, Location location, Player owner) {
        super(new Attack(1, 6, 1), new Defense(1, 4, 2), 10, 4, location, owner);
    }
}

但是比较这个String与制作getClass()相同。我能做什么?有什么想法吗?或任何模式?

2 个答案:

答案 0 :(得分:4)

如果三个类之间没有真正的区别(除了用于初始化它们的值之外),我认为你应该考虑用UnitType enum替换它们(作为一个副作用)解决你所面临的问题。

enum UnitType {
    ARCHER(new Attack(1, 6, 1), new Defense(1, 4, 2), 10, 4),
    LANCER(new Attack(...), ...)
    RIDER(...)

    private final Attack attack;
    private final Defense defense;


    UnitType(Attack attack, Defence defence, firstValue, secondValue) {
        this.attack = attack;
        ......
    }
}

然后您可以使用您的Unit类而无需子类:

class Unit {
    Unit(UnitType unitType, Location location, Player owner) {
        ....
    }

    public UnitType getType() {
        return unitType;
    }
}

这允许您在不定义新类的情况下添加单位类型,并使您能够以直接的方式区分不同的单位。

答案 1 :(得分:0)

我想,你应该采取这个想法

在单元类中,您可以构建新的方法和属性,例如

Public Class Unit {
    //......Your previous design

    //Solve with something like this
    //the path of sprite
    String spriteFolder = "";

    //Your main constructor, content still Your previous design
    //add new parameter to constructor, "sprite"
    Public Unit(Attack, Defense, 15, 5, location, owner,        sprite          ){
        //......Your previous design
        spriteFolder = sprite;
    }

    //this is the solution
    public getSpriteFolder(){
        return spriteFolder
    }

}

你可以调用继承

//this your inheritance system look like
public class Archer extends Unit {    
    public Archer(World world, Location location, Player owner) {
        super(new Attack(1, 6, 1), new Defense(1, 4, 2), 10, 4, location, owner,   "archer/sprite"         );
    }
}

public class Lancer extends Unit {    
    public Lancer(World world, Location location, Player owner){
        super(new Attack(2, 2, 5), new Defense(3,2,3), 15, 5, location, owner,   "lancer/sprite"         );
    }
}

public class Rider extends Unit{    
    public Rider(World world, Location location, Player owner) {
        super(new Attack(3, 2, 4), new Defense(2,4,1), 15, 7, location, owner,   "rider/sprite"         );
    }
}

你可以把它叫做画画

Archer a = new Archer();
Lancer l = new Lancer();
Rider r = new Rider();

a.getSpriteFolder();
l.getSpriteFolder();
r.getSpriteFolder();

或者如果你将它实例化为数组并想要绘制

Unit[] myUnit = new Unit[3];
Unit[0] = new Archer();
Unit[1] = new Lancer();
Unit[2] = new Rider();

for (int i=0; i < Unit.length() ; i++){
    Unit[i].getSpriteFolder();
}