Java 比较方法中的自定义对象
在我的应用程序中(这是一款Android游戏,也就是Java),我有一个名为Quad的自定义类,用于我的游戏对象。该类创建带纹理的openGL四边形 我有另一个类叫做敌人,它扩展了四元组 我有一个从我的游戏类调用的方法,我可以传入各种对象。现在,我想根据传入的对象做不同的事情,我将尝试用一些代码来演示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
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,这迫使我不得不这么做。解释得很好的答案(也让我的代码更具可读性!):-)