Objekte über mehrere Klassen (?)

perryrhodans

Mitglied
Hiho Leute!

Ich habe gerade in der Schule angefangen, Java zu programmieren.
Der einfachheit halber (für ale Anfänger) nutzen wir vorerst ein Paket, das die wichtigsten Befehle beinhaltet, somit haben wir zum Beispiel einen Bildschirm und können Texte darauf ausgeben, ohne den genaueren Java-Code zu kennen.

Jedenfalls habe ich nun ein Problem (was wir bisher noch nicht besprechen):
Ich initiallisier in einer Klasse in einer Methode:
#Klasse initiallisiereAlles:
Code:
Bildschirm bildschirm = new Bildschirm();
Stift           stift          = new Stift();

#Klasse gibAllesAus:
Code:
initiallisiereAlles iA = new initiallisiereAlles();

iA.stift.schreibe("Breite: " +iA.bildschirm.breite() + "Hoehe: " + iA.bildschirm.hoehe());

Diese wird dann von der Main- Klasse aufgerufen. Alles schön und gut, ich bekomme den Bildschirm.
Jedoch wenn ich diesen Bildschirm (z.B. um seine Größe zu ändern oder auszugeben) von einer anderen Klasse starten will, gibt es nur eine NullPointerException.
Würde ich Bildschirm immer neu deklarieren, öffnen sich auch immer wieder neue Bildschirme...
Also, ich bin noch totaler Anfänger, deswegen würde ich mich da über Hilfe freuen

Cya
 
Ich nehme an, dass die Zeile

Stift stift = new Stift();

im Konstruktor ausgeführt wird. Dadurch ist die Sichtbarkeit der Variable stift außerhalb nicht mehr gegeben. So sollte es funktionieren, wenn die Klassen im gleichen package liegen. Wenn nicht, stift als public deklarieren.

Code:
class MyClass
{
Stift stift;
 MyClass()
 {
   stift = new Stift();
 }
}

Je nach Bedarf geht natürlich auch:
Code:
class MyClass
{
Stift stift = new Stift();
 MyClass()
 {
   // mach was
 }
}



Übrigens sind public Variablen i.A. verpönt, besser/sauberer sind getter/setter-Methoden.
Code:
private Stift stift;
public getStift()
{
 return stift;
}

Um dann in der anderen Klasse so darauf zuzugreifen:
Code:
iA.getStift().schreibe("kungFoo");
 
Hm, ich glaube, mien Problem wurd enicht so ganz verstanden,
okay, habe es auch ein wenig schlecht erklärt.
Also, zweiter Versuch (aber vielen Dank Snape ;) ):

Hier habe ich die Startklasse:
Code:
package testmitklassen;

public class StartTest {
  public StartTest() {
  }

  public static void main(String[] args) {
    StartTest startTest1 = new StartTest();

    TestFunktionEins tFE = new TestFunktionEins();

    tFE.getbildschirminfos();
  }
}

So, von hier aus funktioniert ja alles, also die Aufrufe.
Weiter habe ich dann hier die Anwendungsklasse (in der die benötigten Komponenten
wie bildschirm und Stift initiallisiert werden):
Code:
package testmitklassen;
import stiftUndCo.*;

public class TestAnwendung {

  private Bildschirm bildschirm = new Bildschirm();
  // diese Klasse darf nur einmal aufgerufen werden, da er ja sonst wieder einen neuen
  // Bildschirm erstellt... das will ich ja nicht, habe aber keine Lösung dafür
  private Stift stift;
  //okay, mit dem Stift alles fein, nur habe ich ihn doch dann nicht mit new initiallisiert?!
  // heißt doch, er existiert noch nicht wirklich

  public TestAnwendung() {
    return stift;      // -> Meldung: cannot return a value from method whose result
                         //                    type is void 
  }
}

Ich denke, hier besteht mein größtes Problem.
Da ich auch nicht wirklich verstand, was Snape meinte.
Heisst das, dass ich die Objekte im Konstruktor erstellen soll?
Funktionier irgentwie nicht so, keine Ahnung wie es sonst geht.
Zweites Problem, ich kann in initiallisiereAlle -> (iA) keinen Konstruktor
namens getStift() erstellen, ab dann sagt er: invalid method declaration; return type required

Puh, ich bin echt fertig, habe schon so viel versucht, klappt alles nicht.
Bitte bitte helft mir. *verzweifelt sei*

Übrigens, noch der Code, von dem ich dann die Bildschirminformationen erfrage:
Klasse TestFunktionEins:
Code:
package testmitklassen;
import stiftUndCo.*;

public class TestFunktionEins {
  public TestFunktionEins() {
  }
  TestAnwendung tA = new TestAnwendung();

  public void getbildschirminfos(){
   tA.stift.schreibe("Breite: " +tA.bildschirm.breite() + "Hoehe: " + tA.bildschirm.hoehe());
  }

}


Vielen Dank!

Cya
-PerryRhodans-
 
Code:
  public TestAnwendung() {
    return stift;      // -> Meldung: cannot return a value from method whose result
                         //                    type is void 
  }
//okay, mit dem Stift alles fein, nur habe ich ihn doch dann nicht mit new initiallisiert?!
// heißt doch, er existiert noch nicht wirklich

Ein Konstruktor kann keinen Wert via return zurückgeben bzw er kann auf
keine Weise einen Wert zurückliefern... Wie du diesen return value
umgehen kannst und das mit deiner Stiftproblematik hat Snape schon ganz gut
erklärt denke ich...


// diese Klasse darf nur einmal aufgerufen werden, da er ja sonst wieder einen neuen
// Bildschirm erstellt... das will ich ja nicht, habe aber keine Lösung dafür

Wozu mehrmals aufrufen bzw meherere Objekte davon erzeugen?
Das brauchst du ja gar nicht...
Du übergibst dein Objekt tA einfach sämtlichen Methoden mit denen du was mit
tA anstellen willst:
Code:
class MyClass{
  ...
  public void doSomething(TestAnwendung tA){
      System.out.println("Breite: " +tA.bildschirm.breite() + "Hoehe: " + tA.bildschirm.hoehe());
  }
   ...
}

Aufruf:

Code:
package testmitklassen;
import stiftUndCo.*;

public class TestFunktionEins {
  public TestFunktionEins() {
  }
  MyClass c = new MyClass();
  TestAnwendung tA = new TestAnwendung();
   c.doSomething(tA);

  public void getbildschirminfos(){
   tA.stift.schreibe("Breite: " +tA.bildschirm.breite() + "Hoehe: " + tA.bildschirm.hoehe());
  }

}
 
Okay, bis jetzt konnte ich das alles nachvollziehen.
Doch wie sollte meine TestAnwendung- Klasse aussehen, also die, wo Bildschirm und Stift initiallisiert werden?
Und kleine Hilfe, dieses public getStift(){return Stift}, was ist das eigentlich?
Und wo kommt das überhaupt hin?

Vielen Dank nochmal für die Hilfe, bis jetzt habt ihr mich schon ein gutes Stück weiter gebracht!

Cya

PS. Ooooookay, es funktioniert. Mal sehen,immo sieht es noch ein wenig zu krumm aus alles, aber ich werde mal ein wenig damit rumspielen und mich da reinarbeiten!
Vielen vielen Dank!
 
Zuletzt bearbeitet:
perryrhodans hat gesagt.:
Und kleine Hilfe, dieses public getStift(){return Stift}, was ist das eigentlich?

snape hat gesagt.:
Übrigens sind public Variablen i.A. verpönt, besser/sauberer sind getter/setter-Methoden.

public, private, protected sind Zugriffsmechanismen für Klassenmember.
private = nur in Klasse sichtbar
public = überall sichtbar
protected = in Klasse und allen Subklassen sichtbar

Klassenmembers wie dein stift Object sollten aus Sicherheitsgründen damit sie nicht
jeder verändern kann private in deiner Klasse gekapselt werden.
Da du aber jetzt auf diese von andren Klassen kein Zugriff mehr hast, da sie ja
private ist, kann man diese Zugriffsrechte sozusagen feineinstellen in dem
man sich Methoden in der Klasse definiert die einen lesenden und/oder
schreibenden Zugriff auf deine Klassenmember stift definieren. Solche Methoden
heissen getter/setter Methoden.

Code:
public getStift(){return Stift}
bietet dir somit einen lesenden
Zugriff auf deine als private deklarierte Klassenmember stift.
Desweiteren befindet sie sich in der Klasse TestAnwendung da ja dein Stift
Objekt ein Member gerade dieser Klasse ist...

Doch wie sollte meine TestAnwendung- Klasse aussehen, also die, wo Bildschirm und Stift initiallisiert werden?

Auch das hat Snape eigentlich schon beantwortet. Konkret für deinen
Fall könnte es vielleicht so aussehen:

Code:
package testmitklassen;
import stiftUndCo.*;

public class TestAnwendung {

  private Bildschirm bildschirm;
  private Stift stift;

  public TestAnwendung() {  //Konstruktor erschafft und initialisiert Klassenmembers
    bildschirm = new Bildschirm();
     stift = new Stift();
  }
   
   public Stift getStift(){ return stift; } //ermoeglicht lesenden Zugriff auf Stift da er von aussen nicht sichtbar ist
   public Bildschirm getBildschirm(){ return bilschirm; } // dito 
}

Gruß

RedWing
 
Uuund hops... da habe ich einen großen Sprung gemacht!
Vielen Dank RedWing, nun habe ich so einiges gelernt und es funktioniert auch alles FAST so wie ich will.

Leider habe ich trotzdem noch ein Problem... :(

Ich kann den Stift zum Beispiel bewegen, ich kann den Bildschirm neu dimensionieren und auch seine Werte ausgeben, jedoch nicht schreiben, bzw. irgentwas, was
mit zeichnen auf dem Bildschirm zu tun hat...

Es wird immer eine NullPointerException ausgegeben

Hier habe ich einmal TestAnwendung, wo alle deklariert werden, nach dem Muster:

Code:
package testmitklassen;
import stiftUndCo.*;

class TestAnwendung {
  private Stift stift;
  private Bildschirm bildschirm;

   TestAnwendung()
   {
     stift = new Stift();
     bildschirm = new Bildschirm(500,200);
   }

   public Stift getStift(){return stift;}
   public Bildschirm getBildschirm() {return bildschirm;}
}


Ich habe das alles verstanden *freu* :D

So, nun die Ausführung in TestFunktionEins:

Code:
package testmitklassen;

public class TestFunktionEins {
  public TestFunktionEins() {
  }

  public void getbildschirminfos(TestAnwendung tA){
    System.out.println("Hoehe: " + tA.getBildschirm().hoehe()); //funktioniert
    System.out.println("Breite: " + tA.getBildschirm().breite());   //funktioniert
    tA.getStift().runter();                       //sagt der nichts zu, denke, funktioniert auch
    tA.getStift().schreibe("abc");           //java.lang.NullPointerException
  }
}

Anstatt zu Schreiben könnte man auch Linien oder Kreise malen, immer die gleiche Meldung.
Diese Methode wird von der main-Klasse aus gestartet.
Habt ihr ne Ahnung woher das kommt? (bzw. nichts kommt)


Hey, ich habe heute soviel gelernt, *gg* das ist klasse.

Cya
-Perry-
 
Hi,
also so wie du es beschrieben hast kann ich da jetzt keinen Fehler erkennen.

Wie rufst du die Methode denn auf?

Ein möglicher Fall könnte so aussehen:

Code:
TestFunktionEins tF = new TestFunktionEins();
TestAnwendung tA = new TestAnwendung();
tF.getbildschirminfos(tA);

sollte eigentlich funktionieren, aber vielleicht kannst du dein Programm auch mal
als zip mit anhängen...

Gruß

RedWing
 
Zurück