Supportnet Computer
Planet of Tech

Supportnet / Forum / Anwendungen(Java,C++...)

Wie auf Methode in Vaterklasse zugreifen?





Frage

Hallo, ich bins mal wieder... hab das Problem, dass ich nicht weiß, wie ich auf eine Methode in der übergeordneten Klasse zugreifen kann. Mit super geht das nicht oder? Hier mein Code: [code] import java.awt.*; import java.awt.event.*; public class OwnExample extends Frame { public static void main(String[] args) { OwnExample wnd = new OwnExample(); } public OwnExample() { super("Fenster"); setBounds(100,100,250,250); setVisible(true); setMenuBar(new MainMenu(new alistener())); addWindowListener(new wlistener()); } void schliessen() { setVisible(false); dispose(); System.exit(0); } } class alistener implements ActionListener { public void actionPerformed(ActionEvent event) { if (event.getActionCommand().equals("Beenden")) { schliessen(); } } } class wlistener extends WindowAdapter { public void windowClosing() { schliessen(); } } class MainMenu extends MenuBar { public MainMenu(ActionListener alistener) { Menu m; m = new Menu("Datei"); m.add(new MenuItem("Beenden")); m.addActionListener(new alistener()); add(m); } } [/code] Ich meine die Methode schliessen(); Vielen Danke im Voraus mal wieder

Antwort 1 von mr_x_hacker

Hi!

super.methode() brauchst Du, wenn in der Subklasse die Methode der Superklasse überschrieben wurde, nun aber explizit doch die aus der Superklasse aufgerufen werden soll.

In Deinem Code ist das Problem, dass die schliessen() sich in der Klasse "OwnExample" befindet, und die Listener nicht von dieser abgeleitet sind! Also können die sie auch nicht aufrufen...

Um die im gegebene Kontext aufrufen zu können, kannst Du Dir z.B. aus den Events das OwnExample-Objekt holen:


class alistener implements ActionListener
{
  public void actionPerformed(ActionEvent event)
  {
    if (event.getActionCommand().equals("Beenden")) {
      //Das Menuitem hat die Action ausgelöst
      Component mItem = (Component)event.getSource();
      //Das Menuitem ist in der MenuBar
      Component mBar = (Component)mItem.getParent();
      //Die Menubar ist im OwnExample
      OwnExample oe = (OwnExample)mBar.getParent();
      oe.schliessen();
        }
    }
}


Ciao Sascha

Antwort 2 von mr_x_hacker

Upsi, ich hab natürlich wieder übersehen, dass Menu keine Component ist... *grml*

Also der funzende Code:


class alistener implements ActionListener
{
  public void actionPerformed(ActionEvent event)
  {
    if (event.getActionCommand().equals("Beenden")) {
      //Das Menuitem hat die Action ausgelöst
      MenuComponent mItem = (MenuComponent)event.getSource();
      //Das Menuitem ist in der MenuBar
      MenuBar mBar = (MenuBar)mItem.getParent();
      //Die Menubar ist im OwnExample            
      OwnExample oe = (OwnExample)mBar.getParent();
            oe.schliessen();
        }
    }
}


Ciao Sascha

Antwort 3 von Javaneuling

Uff, dass es so kompliziert ist, hätte ich nicht gedacht, aber gut, ich bin ja noch Anfänger.

Vielen Dank ein weiteres mal!

Antwort 4 von mr_x_hacker

Moment - das dieser Fall so kompliziert ist hängt daran, dass Du in einem Listener in einer eigenständigen Klasse - welcher nur einen Event bekommt - auf die Methode eines für diesen Listener komplett "unbekannten" Objektes zugreifen willst!
Es muß also der Event "verfolgt" werden, um an das Fenster zu kommen, in dem der Event-Auslöser liegt...

Würdest Du den Listener z.B. direkt in der "OwnExample"-Klasse an die Komponenten dranhängen, hätte er jederzeit Zugriff auf schließen().

Auch von MenuBar mußt Du nicht wirklich was ableiten, um ein Menü zu erstellen, aber da Du vermutlich Deine Gründe hast, hab ich mal nix dazu gesagt :-)

Genau das gleiche, und viel einfacher, wäre es so:


import java.awt.*;
import java.awt.event.*;

public class OwnExample extends Frame {

  public OwnExample() {
    super("Fenster");
    Menu m;
    MenuItem mi;
    MenuBar mBar = new MenuBar();
    mBar.add(m = new Menu("Datei"));
    m.add(mi = new MenuItem("Beenden"));
	m.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent event){
			schliessen();
		}
	});
    setMenuBar(mBar);
    setBounds(100,100,250,250);
    setVisible(true);

    addWindowListener(new WindowAdapter(){
	  public void windowClosing(WindowEvent we) {
		schliessen();
      }
	});
  }

  void schliessen() {
    setVisible(false);
    dispose();
    System.exit(0);
  }

  public static void main(String[] args) {
    OwnExample wnd = new OwnExample();
  }
}


Ciao Sascha

Antwort 5 von Javaneuling

Oh super, das ist ja richtig einfach.
Hab keine bestimmten Gründe gehabt. Lese nur grad das Buch von Guido Krüger über Java, und da wurde es noch komplizierter gemacht und da hab ich versucht es irgendwie einfacher zu machen. aber wie gesagt, bin ich noch blutiger Anfänger.
Danke schön!

PS Kurze Frage: Dat sind ja jetzt anonyme Klassen, richtig?

Antwort 6 von Javaneuling

Nachtrag:

Warum muss ich denn da jetzt eigentlich nicht mehr von ActionListener ableiten oder von WindowListener? Ist das in Frame schon drinne?

Antwort 7 von mr_x_hacker

Richtig, das sind anonyme Klassen...

Es gibt grundsätzlich mehrere Arten, einen Listener zu verwenden:
Die Methoden addXXXXXListener() erwarten als Argument einen Listener ihrer Sorte, und den kann man ihr auf mehrere Arten übergeben:

1) Deine Weise: Du erstellst eine neue Klasse, welche den Listener implementiert (NICHT ableitet! Die Listener sind Interfaces, keine Klassen! Wenn Du von einer Adapterklasse (WindowAdapter...)ableitest, ist das was anderes, aber Listener werden implementiert!:-))
Wenn Du den Listener an ein Objekt hängt, übergibst Du dann ein Objekt Deiner neuen Listener-Klasse.

2) Meine Methode: Ich mach nicht extra eine neue Klasse, sondern übergebe der add...() ein Objekt einer anonymen Klasse, welches die benötigten Listener-Methoden implementiert, also z.B. die actionPerformed().

3) Auch recht verbreitet:

class Blabla extends Frame implements ActionListener {
  public Blabla() {
    Button b = new Button("Test");
    test.addActionListener(this);
  }
  public void actionPerformed(ActionEvent ae) {...}
}

Das ist so ähnlich wie Deine Methode, nur implementiert in diesem Fall die Klasse mit dem Frame selbst den Listener, und ist somit einer, der mit "this" der add...() übergeben werden kann.
Das wäre auch eine Lösung gewesen, um auf die schliessen() zugreifen zu können, denn wenn die actionPerformed() in der gleichen Klasse ist, kann sie die schliessen() natürlich sehen...

Alle Methoden haben verschiedene Anwendungsbereiche, z.B. sind die anonymen Klassen ganz gut, wenn man nicht immer abfragen will "welcher Button wurden denn nun gedrückt" - man macht ja für jeden Button einen Extra-Listener, und kann damit für jeden einzeln das Verhalten regeln. (3) hat den erwähnten Vorteil, dass man gut auf weitere Elemente der umgebenden Klasse zugreifen kann, also z.B. die schliessen()-Methode...
(2) hab ich bisher eher selten gesehen :-) Die ist wohl angebracht, wenn der Listener noch ein paar andere Dinge tun soll, die man als weitere Funktionalität in die Extra-Klasse schreiben kann...

Ciao Sascha