PDA

View Full Version : [java] Classi interne e metodi di altre classi


andrea
24-07-2007, 09:47
Stavo provando a fare un programmino di esercizio, ma credo di non aver ben capito una cosa sulle classi interne. Da una classe interna è possibile richiamare un metodo di un'altra classe?

Avevo fatto questi frammenti di codice:

public class BounceFrame extends JFrame {
public BounceFrame() {
setTitle("Bounce Test");
setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);

panel = new BouncePanel();
add(panel,BorderLayout.CENTER);

bpanel = new ButtonPanel();
add(bpanel,BorderLayout.SOUTH);
}

public void addBall() {
try {
Ball ball = new Ball();
panel.add(ball);

for (int i = 1; i <= STEPS; i++) {
ball.move(panel.getBounds());
panel.paint(panel.getGraphics());
Thread.sleep(DELAY);
}
}
catch (InterruptedException e) {
}
}

private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;

private static final int STEPS=1000;
private static final int DELAY=3;

private BouncePanel panel;
private ButtonPanel bpanel;
}

e quest'altro dove richiamavo il metodo addBall all'interno di una classe interna:

public class ButtonPanel extends JPanel {
public ButtonPanel() {
JButton startButton = new JButton("Start");
JButton closeButton = new JButton("Close");

add(startButton);
add(closeButton);

ButtonStartAction startAction = new ButtonStartAction();
ButtonCloseAction closeAction = new ButtonCloseAction();

startButton.addActionListener(startAction);
closeButton.addActionListener(closeAction);

}

private class ButtonStartAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
addBall();
}
}

private class ButtonCloseAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
}

ma appunto il programma non funziona dandomi "The method addBall() is undefined for the type ButtonPanel.ButtonStartAction. Quindi questa cosa non si puo' fare?

PGI-Bis
24-07-2007, 11:00
Il fatto che esista un metodo addBall dichiarato in una classe diversa è irrilevante ai fini dell'invocazione dello stesso in un'altra classe, se tra le due classi non esiste una qualche "relazione".

Le "relazioni" che ti permettono di considerare in una classe A le dichiarazioni contenute in una classe B sono il contenimento (A è una classe interna di B) e l'estensione (A extends B).

La dichiarazione della classe ButtonStartAction non è contenuta nella dichiarazione della classe BounceFrame nè ButtonStartAction estende BounceFrame ergo il metodo addBall dichiarato in BounceFrame è "ignoto" a ButtonStartAction.

Esiste poi una seconda questione cioè il fatto che ogni invocazione di metodo richiede l'esistenza di un oggetto che la subisca.

Noi scriviamo addBall() ma, se addBall non è static, allora è "qualcosa.addBall()". L'omissione di "qualcosa" mette in campo il meccanismo predefinito di risoluzione del bersaglio dell'invocazione. Solitamente è "this.addBall" ma, per le classi interne non annidate, può essere [Outer].this, dove "Outer" è il nome di una delle classi che contengono la classe interna. Vale a dire che se:

ButtonStartAction fosse una classe interna non annidata di ButtonPanel

e

ButtonPanel fosse una classe interna non annidata di BounceFrame

allora

addBall() nell'actionPerformed di ButtonStartAction sarebbe l'equivalente di BounceFrame.this.addBall(), con BounceFrame.this automaticamente risolto dal compilatore.

A scanso di equivoci, la questione interna-non interna, è un dettaglio del linguaggio per lo più irrilevante. Nel contesto dell'orientamento agli oggetti, il ruolo delle classi interne del linguaggio di programmazione Java assolve alla mancanza di una sintassi diretta per la dichiarazione definita di un oggetto.