Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 比较方法中的自定义对象_Java_Object_If Statement_Comparison - Fatal编程技术网

Java 比较方法中的自定义对象

Java 比较方法中的自定义对象,java,object,if-statement,comparison,Java,Object,If Statement,Comparison,在我的应用程序中(这是一款Android游戏,也就是Java),我有一个名为Quad的自定义类,用于我的游戏对象。该类创建带纹理的openGL四边形 我有另一个类叫做敌人,它扩展了四元组 我有一个从我的游戏类调用的方法,我可以传入各种对象。现在,我想根据传入的对象做不同的事情,我将尝试用一些代码来演示 bird = new Enemy(); //Create a bird sprite snail = new Enemy(); //Create snail sprite public voi

在我的应用程序中(这是一款Android游戏,也就是Java),我有一个名为Quad的自定义类,用于我的游戏对象。该类创建带纹理的openGL四边形

我有另一个类叫做敌人,它扩展了四元组

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

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”要做的事情,那么我如何才能以更可接受的方式实现我的目标,以及为什么第一种方法被认为是不可接受的?

您可以创建两个类(Bird和Snail),扩展Quad并使用
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();
    }
 }

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

或者创建一个Bird和Snail类,然后让这些类从Quad扩展。然后你可以和我核对一下

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

或者您可以创建一个枚举并向
Quad

添加一个属性。这看起来像是一个使用面向对象语言(Java)但不应用面向对象概念的示例

自然的面向对象方法是在
bird
类中有“bird stuff”的代码,在
snail
类中有特定于snail的代码。在您的示例中,为所有敌人类型共享的代码将进入
敌人
类:

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
    }

    ...
}
然后,您不需要进行丑陋的类型检查来调用特定的行为。您只需调用该方法,就可以调用每种类型敌人的具体实现。如果
BADDEYOUR
EYOUR
类型的变量:

badEnemy.doSomething();

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

Hi@gaetanmasse,谢谢你,在我的实际项目中,我有一个敌人类,它扩展了Quad,bird和snail是这个“敌人”类的对象,你能告诉我如何在我的案例中使用你的方法吗?我将编辑我的问题以显示。。。。。。(我正在简化我的问题代码)。感谢您确保我理解这个@GaëtanMaisse,当我最初创建对象时,我必须传入类型?比如bird=新的敌人(EnemyType.bird);(然后导入EnemyType)?谢谢(我是enums的新手)是的,你几乎是对的:敌鸟=新敌人(EnemyType.bird);(查看一下enum上的小介绍)是的,刚刚更新了我的最后一条评论:-)几乎是在测试,但出于某种原因isBird();似乎不会触发-所以如果我说if(sprite.isBird),它不会返回true,我会检查它以确保所有代码都正确。谢谢。是我太傻了@GaëtanMaisse,我忘了在构造函数中指定mType。所有的测试和工作都非常出色——我一直想学习一下Enum,这迫使我不得不这么做。解释得很好的答案(也让我的代码更具可读性!):-)