比较方法中的自定义对象

时间:2014-10-30 20:04:57

标签: java object if-statement comparison

在我的应用程序(这是一款Android游戏 - 所以,Java)中,我有一个名为Quad的自定义类,我将其用于我的游戏对象。该类创建一个纹理的openGL四元组。

我有另一个名为Enemy的类,它扩展了Quad。

我有一个从我的游戏类调用的方法,我可以传入各种对象。现在,我想根据传入的对象做不同的事情,我将尝试用一些代码进行演示。

bird = new Enemy();  //Create a bird sprite
snail = new Enemy(); //Create snail sprite

public void doSomething(Quad sprite){

    //Do work here regardless of which object was passed in
    move(object);

    if (sprite == bird){
        //Do bird specific stuff here
    }

   else if {sprite == snail}{
       //Do snail stuff here

   }

}

所以,正如你所看到的,我想执行一些公共代码而不管传递给方法的对象(无论是鸟,蜗牛还是其他一些对象),然后在公共代码之后,应该有一些特定的对象代码运行。

现在,我记得在阅读其他一个问题时,虽然这有效但不是正确的事情。

由于代码的比例严重偏向于公共代码,(即,无论对象是什么,方法中的大部分代码都应该运行),创建它似乎不是一个好主意不同的鸟类和蜗牛的方法。代码重复太多。

我可以这样做:

public void doSomething(Quad sprite){

    move(object);

}


 public void doBirdStuff(){

     doSomething(bird);

     //Bird specific code here

 }

public void doSnailStuff(){

     doSomething(snail);

     //Snail specific code here

 }

然后只需调用特定对象,所以:

doSnailStuff(snail);
doBirdStuff(bird);

然而,这似乎过于复杂和低效

所以我的问题是,如果以这种方式比较自定义对象不是'Java'要做的事情,我怎样才能以更可接受的方式实现我的目标,为什么第一种方法被认为是不可接受的呢?

3 个答案:

答案 0 :(得分:1)

您可以创建两个扩展Quad的类(Bird和Snail)并使用instanceof

public void doSomething(Quad sprite){
    //Do work here regardless of which object was passed in
    move(object);

    if(sprite instanceof Bird) {
       //Do bird specific stuff here
    }
    else if {sprite instanceof Snail}{
       //Do snail stuff here
    }
 }

如何使用它的一个例子:

public void main(){
    Bird bird = new Bird();
    Snail snail = new Snail();

    // Do something with a bird
    doSomething(bird);

    // Do something with a snail
    doSomething(snail);
}

更新

因为大多数代码并非特定于bird / snail,所以最好的方法是使用定义敌人类型的枚举:

public enum EnemyType{
    Bird,
    Snail
}

并在你的敌人类中使用它:

public class Enemy extends Quad{

    private EnemyType mType;

    //All other class members...

    // Constructor with type
    public Enemy(EnemyType type){
        this.mType = type;
    }

    public void doEnemyStuff(){
         if(isBird()){
         // Bird Stuff
         }
         else if(isSnail()){
         // Snail Stuff
         }
    }

    //Check if current enemy is a Bird
    public boolean isBird(){
        return mType == EnemyType.Bird;
    }

    //Check if current enemy is a Snail
    public boolean isSnail(){
        return mType == EnemyType.Snail;
    }
}

最后,您可以使用以下方法:

public void doSomething(Quad sprite){
    //Do work here regardless of which object was passed in
    move(object);

    if(sprite instanceof Enemy) {
       //Do enemy specific stuff here
       ((Enemy) sprite).doEnemyStuff();
    }
 }

第一个想法是你创建对象并保留对它们的引用只是为了检查。此外它不应该工作,因为“==”的默认行为是检查引用的相等性(There is关于==运算符的一点解释。)

答案 1 :(得分:0)

创建一个Bird和一个Snail类,让类从Quad扩展。然后你可以查看

if (sprite instanceof Bird) {
    // ...
}

或者您可以创建枚举并将属性添加到Quad

答案 2 :(得分:0)

这看起来像是使用面向对象语言(Java)的一个例子,但不是应用面向对象的概念。

面向自然对象的方法是让代码在Bird类中执行“bird stuff”,在Snail类中使用蜗牛特定代码。在您的示例中概述了这一点,所有敌人类型共享的代码将进入Enemy类:

public class Enemy extends Quad {
    ...

    public void doSomething() {
        // common stuff
    }

    ...
}

然后从这个类中派生出特定的敌人,并使用特定的行为实现方法。这些方法从其基类调用常见行为:

public class Bird extends Enemy {
    ...

    @Override
    public void doSomething() {
        // invoke base method that does common stuff
        super.doSomething();

        // bird stuff
    }

    ...
}

public class Snail extends Enemy {
    ...

    @Override
    public void doSomething() {
        // invoke base method that does common stuff
        super.doSomething();

        // snail stuff
    }

    ...
}

然后你不需要丑陋的类型检查来调用特定的行为。您只需调用该方法,并调用每种类型的敌人的具体实现。如果badEnemyEnemy类型的变量:

badEnemy.doSomething();

这封装了特定敌人类型在类中的所有行为,而其余代码不需要知道有关特定敌人类型的任何信息。当你想引入一种新的敌人时,你只需要使用相同的接口实现一个新的Enemy子类,它将在系统内工作而无需额外的更改。