OOP Den Schritt von Theorie zur Praxis nicht verstanden

r0xta

Mitglied
Hallo zusammen,

ich hab mich mal ein bisschen in OOP eingelesen, und die ganze Sache wie folgt verstanden:

Klasse: definiert Attribute und Methoden
Attribute: Variablen innerhalb Klassen
Methoden: Dienen dem Zugriff auf Atrribute
Lokale Variablen: Variablen innerhalb Methoden
Objekt: konkrete Ausprägung (Instanz???) einer Klasse
Objekt wird angelegt mit Typbezeichnung Objektname = new Methodenname(Werte)
Die Methode die bei der Anlegung eines Objektes aufgerufen wird (Methodenname), wird dabei auch als Konstruktor bezeichnet.

Zwischenfrage: Woher weiß ich von welchem Typ mein Objekt ist? Ist die Typbezeichnung immer gleich dem Klassennamen??



Wenn ich nun aber versuche das ganze in die Praxis umzusetzen, bekomm ich's nicht auf die Reihe:
Code:
Class A {

private javax.swing.JLabel jLabel1; //Mein Attribut in Klasse A

//Meine Methode in Klasse A, die gleichzeitig ein Konstruktor ist, da ich sie in Klasse B aufrufe(??)
public void schreibeLabel(){
        jLabel1.setText("Dieser Text erscheint nun");
    }
}

Code:
Class B {

If Bedingung(true){
/**hier will ich nun schreibeLabel() aufrufen – aber wie?? Muss ich jetzt ein Objekt – eine konkrete Ausprägung – 
von meinem jLabel erstellen? Ist mein Label nicht eigentlich schon eine konkrete Ausprägung???**/
}
}
 
S

SlaterB

Gast
wenn du von B z.B. schreibeLabel() an A aufrufen willst, dann hat das mit JLabel gar nix mehr zu tun,
du brauchst ein A-Objekt (welches du noch nicht hast) und musst daran die Methode aufrufen, nicht mehr und nicht weniger,

eine Methode ist noch lange kein Konstruktor, nur weil sie irgendwo anders irgendwie aufgerufen wird,

den Typ eines Objektes erkennt man im einfachen Fall am Typ der Variablen, ist normalerweise der Klassenname, ja

Java:
class A
{
    private JLabel jLabel1 = new JLabel(); // eine leere Variable bringt wenig, auch ein JLabel anlegen

    public void schreibeLabel()  {
        jLabel1.setText("Dieser Text erscheint nun");
    }
}

class B
{
    public B()  { // Konstruktor von B
        if (true)  {
            A a = new A(); // A-Objekt erstellt
            a.schreibeLabel();
        }
    }
}
 

Painii

Bekanntes Mitglied
Zwischenfrage: Woher weiß ich von welchem Typ mein Objekt ist? Ist die Typbezeichnung immer gleich dem Klassennamen??
Ja, und mehr. Ein Objekt ist vom Typ seiner Klasse und derer von der es erbt (Polymorphie... lies dich rein wenn du das weiter unten verstanden hast :) )


Wenn ich nun aber versuche das ganze in die Praxis umzusetzen, bekomm ich's nicht auf die Reihe:
Code:
Class A {

private javax.swing.JLabel jLabel1; //Mein Attribut in Klasse A

//Meine Methode in Klasse A, die gleichzeitig ein Konstruktor ist, da ich sie in Klasse B aufrufe(??)
public void schreibeLabel(){
        jLabel1.setText("Dieser Text erscheint nun");
    }
}
Das ist noch kein Konstruktor, sondern ein normale Methode.
Einen Konstruktor baust du so:
Java:
public A(){ //A dein Klassenname, wenn du willst in den Klammern noch Argumente
 jLabel1 = new jLabel(); //jLabel() ist der Konstruktor für jLabel-Objekte
}

Code:
Class B {

If Bedingung(true){
/**hier will ich nun schreibeLabel() aufrufen – aber wie?? Muss ich jetzt ein Objekt – eine konkrete Ausprägung – 
von meinem jLabel erstellen? Ist mein Label nicht eigentlich schon eine konkrete Ausprägung???**/
}
}

Java:
A deinObjekt = new A(); //deinObjekt wird jetzt ein konkretes A zugewiesen
deinObjekt.schreibeLabel(); //das konkrete A schreibt jetzt das Label
deinObjekt = new A(); //deinObjekt ist jetzt ein neues A, nichtmehr das alte!
deinObjekt.schreibeLabel(); //hier schreibt dein neues Objekt das jLabel

Ich geh mal weiter auf das JLabel als Beispiel mit den Objekten:
jLabel1 wird mit new ein neues jLabel.
jLabel2 wird mit new ein anderes jLabel.
Beide sind von der Klasse (Typ) JLabel, aber haben verschiedene Ausprägungen (zeigen z.b. verschiedene Texte an)

Hoffe das hilft weiter, wenn nicht weiterfragen - oder mal hier im Forum ein paar Seiten weiterblättern, da gibts auch einige gute Beispiele :)
 

r0xta

Mitglied
Java:
class A
{
    private JLabel jLabel1 = new JLabel(); // eine leere Variable bringt wenig, auch ein JLabel anlegen

    public void schreibeLabel()  {
        jLabel1.setText("Dieser Text erscheint nun");
    }
}

class B
{
    public B()  { // Konstruktor von B
        if (true)  {
            A a = new A(); // A-Objekt erstellt
            a.schreibeLabel();
        }
    }
}

das zielt glaub ich auf das ab was ich erreichen will, aber es kommt ne Fehlermeldung: non-static method schreibeLabel() can not be referenced from a static context


Java:
public A(){ //A dein Klassenname, wenn du willst in den Klammern noch Argumente
 jLabel1 = new jLabel(); //jLabel() ist der Konstruktor für jLabel-Objekte
}

Kann es sein dass du Methodenname, und nicht Klassenname meinst? Bin glaub ich grad bisserl verwirrt...
Was ich glaub verstanden hab, wie ich dann jeweils ein neues jLabel anlege (eine neue Instanz??). Aber wie komm ich jetzt zu meinem Ziel dass ich die Methode schreibeLabel in Klasse B aufrufe, die ja den Text meines Labels verändert? Schon so wie SlaterB es vorschlägt schätze ich?
 
S

SlaterB

Gast
> aber es kommt ne Fehlermeldung: non-static method schreibeLabel() can not be referenced from a static context

bei dir vielleicht mit völlig anderen Code, poste den oder Screenshots,
bei mir gehts
 

Painii

Bekanntes Mitglied
Kann es sein dass du Methodenname, und nicht Klassenname meinst? Bin glaub ich grad bisserl verwirrt...
So meinte ich das:
Java:
public class A{
 public A(){ //Konstruktor hat keinen Rückgabewert und heisst wie die Klasse
 }
}

public class Auto{
 public Auto(){ //Konstruktor für Auto
 }
}

Was ich glaub verstanden hab, wie ich dann jeweils ein neues jLabel anlege (eine neue Instanz??).
Eine neue Instanz machst du mit einem [c]new[/c] :)

Aber wie komm ich jetzt zu meinem Ziel dass ich die Methode schreibeLabel in Klasse B aufrufe, die ja den Text meines Labels verändert? Schon so wie SlaterB es vorschlägt schätze ich?
SlaterB hat eine richtige Lösung gepostet ja.

Wichtig ist halt dass du das Prinzip verstehst:
Du hast ein Objekt (der Klasse A). Deine Klasse A hat ein Objekt der Klasse JLabel.
Wenn du jetzt von deinem B auf ein JLabel von A zugreifen willst, dann muss deine Methode in B ein Objekt der Klasse A haben. Nur über dieses Objekt von A kommst du an das JLabel ran. (Im OOP-Ansatz zumindest)
 
S

SlaterB

Gast
JFrame ist eine Java-Standard-Klasse,
benenne nie eigene Klassen genauso

wahrscheinlich hast du bereits ein JFrame angezeigt und änderst nun den Text in einem neu erzeugten, völlig anderen JFrame,
das bringt natürlich eher wenig, du musst das alte angezeigt JFrame-Objekt ändern,

denkbar sind aber auch eine Vielzahl andere Fehler, am besten den ganzen Code posten
(aber bloß nicht 500 Zeilen wie dein Screenshot vermuten läßt ;), kleine Testprogramme )
 

r0xta

Mitglied
hmhmhm
aber selbst wenn ich die Klasse JFrame umbenenne ändert sich nix.
und die Methode schreibeName (siehe Screenshot 2) ändert ja auch einen Text - und da funktioniert es.

ich geb hier mal die gekürzte variante der Klasse JFrame zum besten.
Vielleicht kann jemand was rauslesen?

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * JFrame.java
 *
 * Created on 17.11.2009, 19:53:56
 */

package labyrinth;

import java.awt.Color;
/**
 *
 * @author anwender_1
 */
public class JFrame extends javax.swing.JFrame {


    public String spieler;
    public String zielLabel;

    /** Creates new form JFrame */
    public JFrame() {
        initComponents();
        setLocationRelativeTo(null);
        getContentPane().setBackground(new Color(150, 120, 90));
        frontLabel.setOpaque(true);
        frontLabel.setBackground(new Color(113, 83, 79));
        

        }

    public void returnSpieler(){
        this.spieler = nameEingeben.getText();
        schreibeName();
    }

    public void schreibeName(){
    frontLabel.setText("  Hallo " + spieler + "!" + "Klicke auf 'Spielen', um das Spiel zu beginnen.");
    }

    public void schreibeZiel(){
        jLabel3.setText("Spiel gewonnen");
    }




    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        exit = new javax.swing.JLabel();
        spielen = new javax.swing.JLabel();
        info = new javax.swing.JLabel();
        highscore = new javax.swing.JLabel();
        frontLabel = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        exit1 = new javax.swing.JLabel();
        nameEingeben = new javax.swing.JTextField();
        spielerAbsenden = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBackground(new java.awt.Color(200, 163, 94));
        setUndecorated(true);

        .........
        .........

      }



    private void spielenMouseClicked(java.awt.event.MouseEvent evt) {                                     
        aMAZEin3D.starteSpiel();
       
}                                    

                              

    private void exitMouseClicked(java.awt.event.MouseEvent evt) {                                  
        System.exit(1);        // TODO add your handling code here:
    }                                 


    private void exit1MouseClicked(java.awt.event.MouseEvent evt) {                                   
        System.exit(1);
    }                                  
                              

    private void exit1MouseEntered(java.awt.event.MouseEvent evt) {                                   
        exit1.setForeground(Color.BLACK);
    }                                  

                                  

    private void highscoreMouseExited(java.awt.event.MouseEvent evt) {                                      
        highscore.setForeground(Color.WHITE);
    }                                     

                                

    private void spielerAbsendenMouseClicked(java.awt.event.MouseEvent evt) {                                             
        returnSpieler();
    }                                            
                                      

                                          



    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                   new JFrame().setVisible(true);

        }


            
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JLabel exit;
    private javax.swing.JLabel exit1;
    private javax.swing.JLabel frontLabel;
    private javax.swing.JLabel highscore;
    private javax.swing.JLabel info;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JTextField nameEingeben;
    private javax.swing.JLabel spielen;
    private javax.swing.JLabel spielerAbsenden;
    // End of variables declaration



}
 

r0xta

Mitglied
Ok, dann hab ich den Satz definitiv nich verstanden, sorry ;)

Ich versteh unter einem JFrame erstmal einfach ein Fenster.
Und ich hab eigentlich auch nur eines angelegt, in dem ich (in NetBeans) auf Files/New File/Swing GUI Forms/JFrame Form gegangen bin. Und das ganze hab ich nur einmal gemacht.

Also kann eigentlich nur ein JFrame existieren? Dann kann ich auch kein altes JFrame-Objekt ändern?
 

ModellbahnerTT

Bekanntes Mitglied
Ich versteh unter einem JFrame erstmal einfach ein Fenster.
Und ich hab eigentlich auch nur eines angelegt, in dem ich (in NetBeans) auf Files/New File/Swing GUI Forms/JFrame Form gegangen bin. Und das ganze hab ich nur einmal gemacht.
Tja, pech gehabt, was nennst du deine Klasse auch JFrame? Jedenfalls legst du in deinem ersten Screenshot-Code ein neues JFrame an und änderst dort irgendeinen Text.
 
S

SlaterB

Gast
in Zeile 504 im ersten Screenshot steht new JFrame(),
an der Stelle ("wenn einer der Spieler den Ausgang erreicht") wird doch wohl nicht das Hauptfenster des ganzen Programms erst erzeugt, oder?
also ist es ein zweites JFrame, irgendwo existiert schon ein erstes, wahrscheinlich in der main-Methode erzeugt

kann natürlich auch sein, dass JFrame irgendein Sonderfenster ist, welches vorher nicht benötigt wird,
solange aber derartige Vorgänge nicht klar sind, ist das hier alles nur raten,

->
vollständige Programme von der main-Methode an posten, und falls es mehrere Fenster gibt, ungefähr erklären, was wo wann wie passieren soll
 

r0xta

Mitglied
Da JFrame ne vordefinierte Klasse ist, darf ich new JFrame() nicht verwenden wenn ich mein Objekt anlege - hab ich das korrekt verstanden?

Wenn ich die Klasse aber nun beispielsweise in Fenster umbenenne passiert aber wie gesagt trotzdem nix.

Dann steht halt beim Objekt anlegen Fenster a = new Fenster()

Oder darf ich allgemein nicht new Klassenname() schreiben??
Aber ne Methode aus meiner Klasse JFrame kann ich hier ja nicht angeben??
 
Zuletzt bearbeitet:
S

SlaterB

Gast
new JFrame() kannst du schreiben, es geht nur darum wann und wie oft du das machst,
nämlich nur einmal, nicht ein zweites Mal,
das funktioniert zwar zunächst auch, du kannst mit new JFrame() in Zeile 504 ohne Fehler ein neues JFrame anlegen,
aber es bringt dir nichts dort irgendwas zu ändern,
denn nur das alte erste JFrame wird auch auf dem Bildschirm angezeigt, bei diesem müßtest du den JLabel-Inhalt ändern
 

r0xta

Mitglied
Ok, das hab ich soweit verstanden.

Aber wie kann ich dann mein Objekt a anlegen wenn ich JFrame a = new JFrame() egtl gar nich machen darf?

Mir ist das Anlegen eines Objektes leider nur vertraut wenn alles innerhalb einer Klasse stattfindet. Mit 2 Klassen komm ich noch nicht zurecht.
 

Spin

Top Contributor
Moin.

Du arbeitest mit GUIBuilder, wie unfair ;) Am besten du schreibt deinen Code selbst und lässt ihn nicht generieren. Kostet ein wenig Zeit und ist gewöhnungsbedürftig, aber du lernst schnell dazu :)

Merke dir, man darf niemlals seine eigene Klasse so nennen, wie sie schon in der Java vordefinition vorhanden ist. Das war auch dein Problem bei JFrame.

JFrame ist die wichtigste Hauptklasse in Swing und ist aus java.awt.Frame abgeleitet.
Das tolle ist, die Klasse stellt dir ein Fenster mit Rahmen , mit Systemmenü und Standart Schaltflächen zu verfügung.

Nun brauchst du die nur noch implementieren(ans Fenster anfügen).

Zu deiner Frage:

Du darfst ein neues Fenster erzeugen, doch (siehe Slater) wirst du dass nie zu gesicht bekommen.
Wenn du ein komplett neues Fenster anzeigen lassen willst mit neuen Inhalt, musst du eine neue Klasse schreiben.


Diese Nennst du
Java:
public class Unterfenster extends JFrame {

}

Dann fügst du alles hinzu.

Dann gehst du zu dein Button und fügst ein Listnener hinzu und schreibst dort:

Java:
new Unterfenster();

Fertig.

PS: Mit der Methode dispose() kannst du dann das andere Fenster schließen.

Später kannst du auch das CardLayout verwenden, wenn du zwischen Panels switchen willst. gruß
 
S

SlaterB

Gast
Spin, doch jetzt nicht schon wieder auf den Klassennamen eingehen, das ist ein separates Problem,
hat aktuell nichts mit dem Fehler zu tun

----

in Zeile 504 gar kein neues JFrame erzeugen, sondern das alte verwenden, wo das ist weiß ich nicht,
am besten in einem Klassenattribut der Klasse zu der Zeile 504 gehört,
das alte JFrame kann man im Konstruktor mitgeben oder sonst wie

Java:
main() {
A a = new A();
B b = new B(a);
}



class B {

A oldA .. Konstruktor ..

public void x() {
   this.oldA.doSomething();
   // statt new A().doSomething()

}

}
 

r0xta

Mitglied
Du darfst ein neues Fenster erzeugen, doch (siehe Slater) wirst du dass nie zu gesicht bekommen.
Wenn du ein komplett neues Fenster anzeigen lassen willst mit neuen Inhalt, musst du eine neue Klasse schreiben.

Also kann ich nicht nach alter AJAX-Manier nur den Text von einzelnen Felder aktualisieren sondern muss ein komplett neues Fenster erzeugen?

Ich hab jetzt mal n zweites Fenster angelegt, welches genau so aufgebaut ist wie das erste.
Hab zum Spielbeginn das erste geschlossen, und das neue zum Spielende aufgemacht.
Das witzige: Im ersten Fenster gibts ne Option seinen Spielernamen anzugeben, anschließend kommt die Meldung "Hallo Spieler..." - und die ist jetzt im zweiten Fenster auch wieder da - und das was sich ändern sollte hat sich nicht geändert. Aber das sollte doch jetzt oder??? :noe:

Ich stell mich einfach zu dämlich an :bahnhof:

Dann mal zu Slaters Vorschlag...
Ich glaub da lass ich mal Screens sprechen

starteSpiel() wird durch einen Klick auf ein jLabel in Fenster1 aufgerufen
 
S

SlaterB

Gast
man muss natürlich auch einen Konstruktor mit dem passenden Parameter definieren und das JFrame-Objekt in einem Klassenattribut speichern,
von selber passiert da nix

in Zeile 73 wieder ein neues Objekt zu erzeugen ist falsch, new Fenster() sollte nur genau einmal im Programm auftauchen,
an alle anderen wird das erste Objekt übergeben
 

Spin

Top Contributor
Ui, da sind ja soviele Fehler drin ;)

PS: Man kann auch den Code hier hinein posten.:toll:

Also in deiner Main:

Java:
public static void main(String[] args) {

// Damit du überhaupt ein Fenster sehen kannst
Fenster1 frame = new Fenster1();
aMAZEin3D game = new aMAZEin3D(frame);
frame.setSize(400,400);
frame.setVisible(true);

}


Wenn das fertig ist , dann startet sich ein Fenster auf dem du komponenten angebracht hast.
Nun sollte da ein Button oder was auch immer zu sehen sein und ein Listener.

Wenn du nun auf die Komponente drückst soll sich die Methode starteSpiel() starten.

starteSpiel() ist void und static, was bedeutet , dass sie mit der Klasse aufgerufen werden kann.
Das wollen wir aber nicht deswegen streiche das static.

Der Vorschlag von Slater nutze.
Angwendet an dein Code:

Java:
JFrame frame;

public aMAZEin3D(Fenster1 frame)
this.frame = frame;

So das sind die Vorbereitungen und dann jetzt:

Im Fenster2:
Java:
Fenster1 frame;

public void starteSpiel() {
   this.frame.start();
}


Dazu muss die Methode start() in der Klasse Fenster1 sein.
Wenn das nicht der Fall ist , dann änder die starteSpiel() Methode einfach mit dem Attribut der Klasse
aMAZEin3D, gruß

(Slater plz verbessern , wenn du es anders meintest)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
CptK Best Practice Algorithmus nach jedem Schritt zum Visualisieren pausieren Java Basics - Anfänger-Themen 3
O Ziehen im Array um einen Schritt in eine einzige beliebige Richtung Java Basics - Anfänger-Themen 5
steven789hjk543 Erste Schritte java programmieren/ Schritt für Schritt Java Basics - Anfänger-Themen 14
kokojamboo92 mir fehlt ein Schritt.. Java Basics - Anfänger-Themen 10
P Zwei Methoden in einen Schritt zusammenfassen Java Basics - Anfänger-Themen 8
S JSlider Schritt Größe Java Basics - Anfänger-Themen 5
T Swingeinführung Schritt für Schritt Java Basics - Anfänger-Themen 35
I Programmdurchläufe Schritt für Schritt sehen. Java Basics - Anfänger-Themen 5
B schritt nach vorne Java Basics - Anfänger-Themen 10
G Der Schritt vom Java-Entwickler hin zum Homepagebauer Java Basics - Anfänger-Themen 4
E Wer hilft mir schritt für schritt? Java Basics - Anfänger-Themen 5
M Verkettete Liste (schritt für schritt durchlauf) Java Basics - Anfänger-Themen 5
Y Pointer / Referenz - Theorie Java Basics - Anfänger-Themen 3
B Theorie Rot-Schwarz-Bäume Java Basics - Anfänger-Themen 2
A string-theorie Java Basics - Anfänger-Themen 1
MiMa Vererbung Theorie OK, Praxis ?? Java Basics - Anfänger-Themen 4
Y Theorie: Abstract Method Java Basics - Anfänger-Themen 6
P OOP-Theorie-Frage: Referenz auf Objekt Java Basics - Anfänger-Themen 27
M Eine kleine Frage bzw kleine Theorie frage String[arg] Java Basics - Anfänger-Themen 6
E Generics-Theorie Java Basics - Anfänger-Themen 2
J Eine theoretische Frage zur Praxis - JPanel oder Canvas Java Basics - Anfänger-Themen 5

Ähnliche Java Themen


Oben