setCommandListener(this)
заметно легче читать в «игрушечном коде».Я думаю, именно поэтому я видел, что он используется во многих учебниках начального уровня, где авторы просто не хотят углубляться.
Похоже, что начинающие программисты просто слепо копируют этот антишаблон из учебников, не вдаваясь в подробности.
Хотя для более сложного кода, по моему опыту, setCommandListener(new CommandListener(){/*..*/})
было намного проще поддерживать и читать.
Обратите внимание, что выможет получить доступ к полям класса в обоих случаях, только последний требует использования Квалифицировано это :
//import javax.microedition.midlet.*;
//import javax.microedition.lcdui.*;
abstract class ListenerTest extends MIDlet {
protected Display display;
protected void startApp() {
display = Display.getDisplay(this);
Form form = new Form("welcome");
form.addCommand(new Command("go", Command.OK, 1));
form.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable d) {
// qualified this - see JLS 15.8.4
ListenerTest.this.cmdAction(c, d);
}
});
// display "welcome" screen with "go" command
display.setCurrent(form);
}
protected void pauseApp() { }
protected void destroyApp(boolean unconditional) {
notifyDestroyed();
}
protected abstract void displayNext();
private void cmdAction(Command c, Displayable d) {
// invoke from listener to display next screen
displayNext();
}
} // ListenerTest
class NextTest extends ScreenTest {
protected void displayNext() {
Form form = new Form("bye-bye");
form.addCommand(new Command("EXIT", Command.EXIT, 1));
form.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable d) {
notifyDestroyed();
}
});
// display "bye-bye" screen with "exit" command
display.setCurrent(form);
}
} // NextTest
Кстати, я упоминал, что вышеупомянутый подход также безопаснее?Это гарантирует, что слушатель, которого вы ожидаете для определенного экрана, именно тот, который вы установили.
Скажем, если вы сделаете прямую перезапись на setCommandListener (this) и запустите его, выобратите внимание на странное поведение - команда "go" теперь будет выходить из мидлета вместо отображения следующего экрана:
// don't do that
abstract class ListenerTest extends MIDlet implements CommandListener {
protected Display display;
protected void startApp() {
display = Display.getDisplay(this);
Form form = new Form("welcome");
form.addCommand(new Command("go", Command.OK, 1));
form.setCommandListener(this);
// display "welcome" screen with "go" command
display.setCurrent(form);
}
protected void pauseApp() { }
protected void destroyApp(boolean unconditional) {
notifyDestroyed();
}
protected abstract void displayNext();
public void commandAction(Command c, Displayable d) {
// invoke from listener... really??? check the subclass
displayNext();
}
} // ListenerTest
class NextTest extends ScreenTest implements CommandListener {
protected void displayNext() {
Form form = new Form("bye-bye");
form.addCommand(new Command("EXIT", Command.EXIT, 1));
form.setCommandListener(this);
// display "bye-bye" screen with "exit" command
display.setCurrent(form);
}
public void commandAction(Command c, Displayable d) {
// you may not notice but...
notifyDestroyed();
// ...this actually overrides superclass implementation
}
} // NextTest