Warum wird hier 200 ausgeliefert?

Vulymuz

Aktives Mitglied
Java:
public class Auto{

     private int ps;

     public Auto (int ps){
          this.ps = ps;
     }
     public int getPs(){
           return this.ps;
     }
}

Java:
public class BMW extends Auto{

     public void pimp(){
           this.ps += 20;  // Compile-Error: Variable "ps" nicht bekannt
     }
}

Java:
BMW myBmw = new BMW(200);
myBmw.getPs(); // <- liefert "200", also gibt es "ps" scheinbar doch ?!

Abgesehen davon dass es "ps" scheinbar doch gibt: Woher nimmt ps den Wert 200 an?
 
Du übergibst doch im Konstruktor den Wert 200, da kommt der her.

ps muss außerdem entweder protected oder ohne modifier sein, sonst kannst du in den unterklassen nicht drauf zugreifen.
 
Das dachte ich mir, doch wo weise ich der Instanzvariablen den Wert zu? Etwa bei:

Java:
public Auto (int ps){ // wird hier Auto durch BMW erweitert? Hier ist int ps nämlich ein Parameter, sodass die 200 als Argument hier Sinn machen würden. Ansonsten wüsste ich nicht wo ich der Instanzvariablen den Wert zuweise...
          this.ps = ps;
     }
 
Java:
this.ps = ps;
Ja genau da.
Code:
this.ps
ist die Instanzvariable.
Code:
ps
ist der Parameter des Konstruktors.
 
Okay, also können auch Konstruktoren("Klassen" - richtig beschrieben? -) Parameter erhalten? Also praktisch "public class Auto(int s)"?

... und wie kann "this" eine Instanzvariable sein? Ich dachte bisher, mit "this." könne man nur Methoden aufrufen ...

Edit: Wäre this.ps btw nicht nur eine lokale Instanzvariable? Wie kann also getPs darauf zugreifen?
 
Konstruktoren("Klassen" - richtig beschrieben? -)
Nein, Konstruktoren sind keine Klassen.

Also praktisch "public class Auto(int s)"?
Nein.

... und wie kann "this" eine Instanzvariable sein? Ich dachte bisher, mit "this." könne man nur Methoden aufrufen ...
this ist keine Instanzvariable, aber this.ps ist eine.

Schau dir vielleicht nochmal die Grundlagen an, die scheinen noch nötig zu sein 🙂
 
Jetzt habe ich es verstanden...

dieses "return this.ps;" greift gar nicht auf die private Instanzvariable "private int ps;" zurück, sondern auf die - in dem Falle - öffentliche(!) Instanzvariable "int ps", die als Parameter in der Methode Auto angegeben ist. Praktisch eine Setter- und Getter-Methode, richtig?

Doch wieso ist vor "public [wieso ist hier kein Rückgabetyp] Auto (int ps)" nichts?

Und wie gesagt, ist this.ps eigentlich keine lokale Instanzvariable? Wie kann also "return this.ps;" darauf zugreifen?
 
dieses "return this.ps;" greift gar nicht auf die private Instanzvariable "private int ps;" zurück, sondern auf die - in dem Falle - öffentliche(!) Instanzvariable "int ps", die als Parameter in der Methode Auto angegeben ist.
Nein, das ist falsch. der getter greift auf die private Instanzvariable zurück. Du hast keine öffentlich Instanzvariable.

Doch wieso ist vor "public [wieso ist hier kein Rückgabetyp] Auto (int ps)" nichts?
Weils dein Konstruktor ist, die haben keine Rückggabewerte.
 
getPs() ist public, also ist darauf von außen zugreifbar

ps ist private, von außen ist darauf nicht zugreifbar

ps kann durch getPs() auch nach außen transportiert werden

pimp() hat aber keinen (Schreib)-Zugriff auf die private Instanz-Variable ps


Entweder ps protected/default deklarieren oder einen Setter hinzufügen
 
Irgendwie ergibt das keinen Sinn ...

Du sagst ja, dass "this.ps" eine Instanzvariable ist, gleichzeitig aber, dass ich darauf nicht zugreifen kann bei "return this.ps;" (eben da es ja eine lokale Instanzvariable ist), doch wieso kommt dann überhaupt 200 raus? Versetzt

Java:
public Auto (int ps){
          this.ps = ps;
     }

hier "this.ps = 200" den Wert von "private int ps;" auf 200? Selbst wenn, ich kann doch trotzdem weiterhin nicht darauf zugreifen, da es ja private ist.

Übrigens lässt sich das gar nicht kompilieren (-.-):

Java:
Compiliere C:\Users\Alireza\Desktop\Ordnersammlung\Schule & Bildung\Informatik\Privat\Informatik Spielekiste\Parameter & Argumente\Wetterfrosch\halloman.java mit Java-Compiler
halloman.java:5:17: error: constructor BMW in class BMW cannot be applied to given types;
    BMW myBmw = new BMW(200);
                ^
  required: no arguments
  found: int
  reason: actual and formal argument lists differ in length
.\BMW.java:1:8: error: constructor Auto in class Auto cannot be applied to given types;
public class BMW extends Auto {
       ^
  required: int
  found: no arguments
  reason: actual and formal argument lists differ in length
2 errors
 
Dass das nicht kompiliert ist klar. Zum einen passt der Modifier bei ps nicht, außerdem brauchst du einen Konstruktor in der Klasse BMW der den Konstruktor von Auto entsprechend aufruft.

Du sagst ja, dass "this.ps" eine Instanzvariable ist, gleichzeitig aber, dass ich darauf nicht zugreifen kann bei "return this.ps;"
Wo steht denn das?!
 
Private Elemente, werden bei der Vererbung nicht mit vererbt!
Achja, du kannst innerhalb der Klasse auch auf als private deklarierte variablen zugreifen.
Nur von außen halt nicht 🙂 Ich glaube, dass hast du noch nicht ganz verstanden, oder?
 
Return heißt ja, dass die (Public) methode deinen Wert zurück gibt.
Die Methode ist öffentlich.
Das attribut (ps) ist privat.
die öffentliche Methode kann zugreifen, und so einen Wert erfragen.
Der Benutzer kann aber nicht auf das private Attribut zugreifen, sodnern nur über die Methode (einen) Wert erfragen.


PS: Die Angegebenen Zeilen sind im Wesentlichen schonkorrekt. Aber, in welchem Context du das kompilierst sehen wir nicht.
 
Wo steht denn das?!

Na ja, this.ps ist doch eine lokale Instanzvariable, also wie kann man in einer anderen Methode beim Aufruf "return this.ps;" noch darauf zugreifen? Die Instanzvariable ist schließlich nur in dem Block von "public Auto (int ps)" gültig...

Falls ich doch darauf zugreifen kann, dann ist mir alles klar ... auch wenn ich nicht verstehe, wie "this.ps" eine Instanzvariabe sein kann ohne jeglichen Typ oder so.
 
Du hast die Variable im Klassenkopf deklariert, somit ist sie in der ganzen Klasse vorhanden, bis eben der Block geschlossen wird 🙂

Hättest du sie im Konstruktor deklariert, wäre sie nur dort sichtbar.


Du hast eine Variable deklariert:
private int ps.

Mit dem schlüsselwort this, wird das "eigene" Objekt referenziert.
 
Zuletzt bearbeitet:
Alles klar, verstanden. Ich lese mir gerade die Seite durch, will aber heute noch das Problem gelöst haben 🙂D):

Aber wieso wird überhaupt 200 ausgegeben, wenn "int ps" doch private ist? Etwa weil die Getter-Methode public ist?
 
Ich hab doch private int ps; im Klassenkopf deklariert ...

ODER - wie gesagt - versetzt "this.ps" den Wert von "private int ps;" am Anfang auf 200?

Wenn du ne Klasse definierst, meinetwegen die Klasse Auto (Public class Auto) und du willst eine Instanz dieser Klasse erzeugen, dann braucht es einen Konstruktor.
Der Konstruktor ist eine Methode in deiner Klasse Auto und hat den Namen Auto.
Java:
public class Auto
{
   private int ps;
   public Auto(int ps){
     this.ps = ps;
   }
}
wenn du jetzt mit "new" eine Instanz von Auto erzeugst
Code:
Auto bmw = new Auto(200);
bedeutet das, dass der Konstruktor aufgerufen wird. Dieser Konstruktor dient daszu gewisse Startkonditionen zu erzeugen. Bei deinem Konstruktor wird eben durch den Konstruktor der internen Variablen die Motorleistung in PS zugewiesen.
Du hast dann eine Instanz (Objekt) der Klasse Auto, in der gespeichert ist, wieviel ps das Auto hat.
Du kannst darauf aber nicht zugreifen.
Erst wenn du der Klasse auch noch eine öffentliche Methode mitgibst, die z.B. das Abfragen des Wertes ermöglicht..
Java:
public class Auto
{
   private int ps;
   public Auto(int ps){
     this.ps = ps;
   }
   public int getPS(){
     return (ps);
   }
}

und du nun also ein Objekt der Klasse Auto erzeugst
Code:
Auto bmw = new Auto(200);
, dann kannst du anschliessend auch z.B. mit
Code:
System.out.println(bmw.getPS())
die Motorleistung anzeigen lassen.
Du greifst damit nicht direkt auf die interne Variable der Klasse zu, sondern deine Zugriffsmöglichkeiten werden über die öffentlichen Methoden geregelt.
Hast du nun auch noch deine Methode pimp() eingebaut
Java:
public class Auto
{
   private int ps;
   public Auto(int ps){
     this.ps = ps;
   }
   public int getPS(){
     return (ps);
   }
   public void pimp(){
     this.ps += 20;
   {
}

Java:
public class MeineAutos{
   public static void main(String[] args)
   {
   Auto bmw = new Auto(200); 
   System.out.println(bmw.getPS());
   bmw.pimp();
   System.out.println(bmw.getPS());
   bmw.pimp();
   System.out.println(bmw.getPS());
   bmw.pimp();
   System.out.println(bmw.getPS());
   }
}
dann führt jeder Aufruf von bmw.pimp(); zu einer Erhöhung der Motorleistung. Probiers einfach aus.
 
Zuletzt bearbeitet von einem Moderator:
Bei deinem Konstruktor wird eben durch den Konstruktor der internen Variablen die Motorleistung in PS zugewiesen.

Meinst du mit "der internen Variablen" diese hier:

Java:
public class Auto
{
   private int ps;
   public Auto(int ps){ // <- diese hier: "int ps"? oder ...
     this.ps = ps; // <- diese hier: "this.ps"?
   }
   public int getPS(){
     return (ps);
   }
}
 
Schreib mal anstatt
Code:
public Auto(int ps) {
}

das hier:
Code:
public Auto(int pferdestaerke) {
}

Vielleicht wird dir der Unterschied dann klarer. Dann kannst du btw. auch das
Code:
this
weglassen.
Und im Konstruktor ist das dann ein Parameter und keine "interne Variable".
 
aber fehlt nicht eh der Konstruktor mit dem Parameter des BMWs? .... oder sollte ich ins Bett 0o

Wenn eine Subclass instantiiert wird, wird normalerweise der default-Konstruktor der vererbenden Klasse aufgerufen. Da Auto aber schon einen Konstruktor hat ( public Auto (int ps) ), lässt sich der Code wahrscheinlich gar net compilieren

[EDIT]Mein Versuch bestätigt das:
cannot find symbol
symbol: constructor Auto()
location: class javaforum.Auto
Dadurch, dass in Auto mindestens ein Konstruktor angegeben wurde, wird kein default-Konstruktor hinzugefügt

Irgendetwas wurde also wahrscheinlich weggelassen, sonst kann es auch nicht zu der beschriebenen Ausgabe kommen[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
Schreib mal anstatt
Code:
public Auto(int ps) {
}

das hier:
Code:
public Auto(int pferdestaerke) {
}

Vielleicht wird dir der Unterschied dann klarer. Dann kannst du btw. auch das
Code:
this
weglassen.
Und im Konstruktor ist das dann ein Parameter und keine "interne Variable".

Danke, habs schon verstanden, wollte nur wissen, was er mit "interne Variable" meint. Kann es mir sonst einer sagen (er's off :x)? Danke!
 
...
[EDIT]Mein Versuch bestätigt das:

Dadurch, dass in Auto mindestens ein Konstruktor angegeben wurde, wird kein default-Konstruktor hinzugefügt

Irgendetwas wurde also wahrscheinlich weggelassen, sonst kann es auch nicht zu der beschriebenen Ausgabe kommen[/EDIT]

Versteh nicht, was du sagen willst.
Der Code funktioniert .. fast. Man muss nur in der Klasse Auto die schliessende geschweifte Klammer richig herum machen.
 
Was ja dann doch "int ps" wäre, oder nicht?

Genau, mit interner Variablen meine ich diese private int ps.
Wenn du ein Objekt dieser Klasse anwendest, weisst du nicht bzw. musst nicht wissen, wie das intern gehandhabt wird.
Da könnten genausogut 2 interne Variablen sein. Eine, die immer den Anfangswert behält und eine andere, die nur Veränderungen erfasst. Dann könnte da eine Methode reset() sein, um wieder auf den Anfangswert zurückstellen.
 
Ein Auto ist hier ein Objekt.
Ein Objekt enthält Methoden und Variablen.

Ganz im Ernst: besorg dir bitte mal ein Einsteigerbuch und lies zumindest die ersten paar Kapitel.
 
Mit Objekt meine ich die Instanz deiner Klasse Auto, den bmw.
Du kannst auch noch andere Instanzen erzeugen z.B. audi, vwgolf, mitotyo oder wie sie alle heissen.
und bei der Erzeugung jedem dieser Objekte einen andere Motorleistung verpassen.
 
Versteh nicht, was du sagen willst.
Der Code funktioniert .. fast. Man muss nur in der Klasse Auto die schliessende geschweifte Klammer richig herum machen.

Das sind auch wieder Grundlagen: Ohne Angabe von super(...) wird immer der Standardkonstruktor aufgerufen. Weil der aber nicht vorhanden ist (weil ein anderer angegeben wurde), lässt sich der Code nicht compilieren

Frage und meine Antwort bezog sich auf: http://www.java-forum.org/java-basics-anfaenger-themen/140029-hier-200-ausgeliefert.html#post928160

Und ja, hinke dem Thema ein bisschen hinterher... Gut beobachtet 😉
 
Naja hüteüberhüte,

Freilich, wenn wir schon bis zur Vererbung vorgedrungen wären, hätte man dann vielleicht z.B. erklären müssen, dass, wenn es in der Elternklasse nur einen Konstruktor mit Parametern gibt, dieser dann in der erbenden Klasse auch explizit aufgerufen werden muss.

Java:
public class BMW extends Auto 
{
    // Konstruktor der Elternklasse aufrufen
    public BMW(int ps) {
    	super (ps);
    }   
}

vielleicht warst du dann also auch schon etwas zu weit....
 

Zurück
Oben