在我的应用程序(这是一款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'要做的事情,我怎样才能以更可接受的方式实现我的目标,为什么第一种方法被认为是不可接受的呢?
答案 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
}
...
}
然后你不需要丑陋的类型检查来调用特定的行为。您只需调用该方法,并调用每种类型的敌人的具体实现。如果badEnemy
是Enemy
类型的变量:
badEnemy.doSomething();
这封装了特定敌人类型在类中的所有行为,而其余代码不需要知道有关特定敌人类型的任何信息。当你想引入一种新的敌人时,你只需要使用相同的接口实现一个新的Enemy
子类,它将在系统内工作而无需额外的更改。