Konstruktoren bei der Vererbung

hi,

jango, da du meinen thread nicht geöffnet hast, habe ich einen neuen aufgemacht. so diesmal habe ich aber den code mitgepostet…



public class A
{
  public static double x = 1;
  
  public A()
  {
    this(4);
  }
  
  public A(double x)
  {
    A.x += x; 
  }
  
  public void f(double x)
  {
    x+=2*x;
  }
}



public class B extends A
{
  public int y = 3;
  public B(int x)
  {
    super();
    y++;
  }
  
  public void f(int x)
  {
    A.x +=x;
  }
  
  public void f(double x)
  {
    A.x -= x;
    y--;
  }
}




public class M
{
  public static void main (String [] args)
  
  A a = new A(A.x);
  System.out.println(a.x);
  
  a.f(10); 
  System.out.println(a.x);
  
  B b = new B(10);
  System.out.println(b.x + " " + b.y);
  
  b.f(10);
  System.out.println(b.x);
  
  a=b;
  
  a.f(1.0);
  System.out.println(a.x + " " + b.y );
  
  a.f(10);
  System.out.println(a.x);
  
}

so meine frage war, jetzt:

so, nach der zeile A a = new A(A.x); wird doch a.x=2.0. vorher war x =1. jetzt wird die statische variable zu 2.0. der funktionsaufruf a.f(10) ändert ja auch nichts an dem wert. es ist immer noch 2.0.

nun gehts ab: in der zeile B b = new B(10) wird ja ein neues objekt der klasse B erzeugt. dieser übernimmt doch alle attribute und methoden der oberklasse und erweitert sie. heißt das also, auch dass die statische variable public static double x= 1 (Anfangswert) übernommen wird, oder die veränderte statische variable public static double x=2.0; ?

mein compiler sagt mir, dass x = 2.0 übernommen werden muss, da nach

B b = new B(10)
System.out.println(b.x + " " + b.y); 

nicht b.x=5.0 b.y=4 rauskommt, sondern b.x=6.0 b.y=4 rauskommt.

und als ich das gesehen hab, dachte ich sofort an den abschnitt der klassenvariablen in meinem java-buch. hab also das buch aufgeschlagen, und den abschnitt über static-variablen gelesen, und da stand drin, dass sich die klassenvariablen auf die objekte beziehen bz., dass die klassenvariablen für alls objekte gleich sind. sprich wenn sie sich ändert, gilt das für alle objekte…nicht nur für eins…

ich hoffe das reicht als eigenarbeit…ach ja, und an alle die mir antworten wollen:
antwortet bitte nur dann, wenn ihr wirklich helfen wollt, es macht einen echt runter, wenn man das ganze lernen will, und wenn da solche behinderten kommentare kommen wie : “…die frage hättest du dir sparen können, wenn du zwei klassen geschrieben hättest…blabla…” oder wenn ich lese, dass ich nur aus faulheit kurze fragen stelle und keine codes schreibe…nicht wahr, Uhres ??
also ich wiederhole es nochmal: nur antworten wenn man WIRKLICH helfen will…

Ich hätte ihn auch wieder aufgemacht, aber Geduld!
Ich habe auch noch andere Sachen zu tun - ok, lassen wir es so.

Ja, static ist was anderes (davon war im anderen Thread auch nicht die Rede). Die Änderung an einer static-Variable bezieht sich auf die Klasse, und damit auch auf alle Klassen, die von dieser Klasse erben (das war die Frage, falls ich das richtig verstanden habe…?!)

Trotzdem wäre etwas Kontext hilfreich. Bisher sieht das aus wie eine Mischung aus SCJP-Fragen, und Aufgaben, die Erstsemestlern gestellt werden, und die absichtlich so “verwirrend” gestellt werden, dass man (selbst wenn man die Antworten eigentlich kennt) genötigt ist, länger drüber nachzudenken. Aus “didaktischer Sicht” mag das OK sein, aber ein bißchen fragwürdig ist es schon: ‘public static’ (ohne ‘final’) ist ein no-go (das MACHT man einfach nicht :twisted: ) und dieses static-rumgereiche (und Parameter (außerhalb von settern) genauso wie (static) Fields zu nennen) hat mit der Praxis ebenso nichts zu tun…

ja, danke…ja, das sind wirklich aufgaben fürs erste semester. wir kriegen quasi einen code und da müssen wir den aufrufen folgend die werte der attribute etc. angeben.

deshalb versuche ich so viele codeanalyse-aufgaben wie möglic zu lösen, damit ich ein gefühl dafür kriege, worauf ich zum beispiel schauen muss oder worauf ich achten muss etc…

hab auch ehrlich gesagt/geschrieben so langsam den dreh raus…

Hmja… ist ein bißchen schwierig. Eigentlich würde man sagen: “Kick die Übungsaufgaben in die Tonne und denk’ dir selbst was aus - die relevanten Fragen stellen sich da früher oder später automatisch”. Aber… man muss wohl… damit rechnen (oder sogar davon ausgehen) dass “solche” Aufgaben auch in Klausuren gestellt werden… da kann üben nicht schaden…-_-

kaum habe ich das gefühl, ich habe das jetzt endlich verstanden taucht ein anderes problem auf, das ich nicht begreife…also ich habe folgenden code:


public class A 
{
  public int x = 0;
  public A() 
  {
    this.x = 1;
  }
  
  public void f(double x)
  {
    this.x += (int) x;
  }
}



public class B extends A
{
  public int x = 2;
  public B() 
  {
    this.x = 3 + super.x;
  }
  
  public void f(double x)
  {
    this.x +=5;
  }
  
  public void f(int x)
  {
    this.x +=10;
  }
  
  
}


public class M 
{
  public static void main (String [] args)
  {
    A a = new A();
    System.out.println(a.x);
    a.f(2);
    System.out.println(a.x);
    B b = new B();
    System.out.println(b.x);
   }
}

ich versteh nich wieso bei der letzten zeile System.out.println(b.x); nicht b.x=3, sondern b.x = 4 rauskommt? wenn ich doch das objekt b erzeuge, dann nehme ich doch die anfangswerte der attribute von der oberklasse. d.h. wenn da super.x steht, dann nimmt man doch x=0. dann muss doch der konstruktor this.x = 3+0, rechnen, oder?

edit: der aufruf super.x greift doch auf das verdeckte attribut der oberklasse A und der der ist doch zudem zeitpunkt null.

ach jetzt weiß ich wieso, immer wenn ich ein Objekt der Klasse A erzeuge wird, der x-Wert des Objektes mit 1 initialisiert, denn in dem parameterlosen Konstruktor von A steht ja this.x = 1; also wird x bei der erzeugung immer auf 1 gesetzt.

edit : habe ich mir die antwort auf meine eigene frage selber gegeben? falls ja, wird mich das echt freuen. falls nicht, dann stürze ich von einer krise in die nächste…bis zur klausur habe ich noch eine woche und das sollte schon so langsam sitzen…:wink:

Kein Grund zur Krise: Die letzte Erkenntnis war wohl richtig. Aber auch da wieder die Praxisrelevanz: Man sollte sher vorsichtig sein, wenn man von einer erbenden Klasse schon im Konstruktor auf die Fields der Klasse zugreift, von der man erbt. Ist eigentlich eine “Worst Practice” -_-

ja, bis jetzt dachte ich immer ich nehme einfach die anfangswerte der attribute der oberklassen. aber jetzt weiß ich, dass das nicht immer so ist. beim üben bin ich jetzt auf zwei fälle gestoßen, wo das nicht geklappt hat. erstens: wenn das attribut was man erbt eine statische variable ist, und vor der übernahme geändert wurde. und zweitens: in dem oben genannten fall, wenn der konstruktor von der oberklasse einem einen strich durch die rechnung macht.