Programmanalyse

paco89

Bekanntes Mitglied
hallo,

ich habe eine frage zu folgender aufgabe:

a) gegeben sei das folgende JAVA-Programm. Dieses Programm gibt 6 Zeilen Text in der Form v[0]: Unterklasse(Oberklasse(name= Attribut(name1)), name=2) auf der Konsole aus. Tragen Sie die Ausgabe an den markierten Stellen in den Kommentaren ein:

Java:
class Verwendet 
{
  int a; 
  Verwendet (int i)
  {
    a = i;
  }
    public String toString()
    {
      return "Verwendet(a=" + a + ")"; 
    }
  
  
}

Java:
class Ober
{
  Verwendet verw;
  
  Ober(Ober o)
  {
    verw = o.verw;
  }
  
  Ober (int i)
  {
    verw = new Verwendet(i);
  }
  
  public String toString()
  {
    return "Ober(verw=" +verw+ ")";
  }
  
  void f(int x)
  {
    verw.a += x;
  }
  Ober kopie()
  {
    return new Ober(this);
  }
}





Java:
class Unter extends Ober
{
  int b = 4;
  Unter()
  {
    super(100);
  }
  
  Unter(Unter o)
  {
    super(o);
    b = o.b;
  }
  
  Unter(int i)
  {
    this();
    b = i+5;
  }
  
  public String toString()
  {
    return "Unter(" + super.toString() + " , b =" + b + ")";
  }
  
  void f(int x)
  {
    super.f(x);
    b -= x;
  }
  
  void f(short x)
  {
    b += x;
  }
  
  Unter kopie()
  {
    return new Unter(this);
  }
}


Java:
class Programm
{
  static public void main (String [] p)
  {
    Ober[] v = new Ober[3];
    
    v[0] = new Unter(15);
    v[1] = v[0].kopie();
    
    System.out.println("v[0] : " + v[0]);        //Unter(Ober(verw=Verwendet(a=___)), b=___)
    System.out.println("v[1] : " + v[1]);       //Unter(Ober(verw=Verwendet(a=___)), b=___)
   

    v[0].f(1);
    
    System.out.println("v[0] : " + v[0]);      //Unter(Ober(verw=Verwendet(a=___)), b=___)      
    System.out.println("v[1] : " + v[1]);      //Unter(Ober(verw=Verwendet(a=___)), b=___)
   
    v[1].f((short)2);
    
    System.out.println("v[0] : " + v[0]);      //Unter(Ober(verw=Verwendet(a=___)), b=___)
    System.out.println("v[1] : " + v[1]);      //Unter(Ober(verw=Verwendet(a=___)), b=___)
    
    
  }

}


jetzt meine ergebnisse:
In der Klasse "Programm" wird zunächst in der main-methode ein array mit dem namen v vom Typ Ober und mit ingesamt 3 feldern erzeugt. Das 1. feld v[0] zeigt auf ein Objekt vom Typ Unter. Beim erzeugen des objektes wird gleichzeitig der konstruktor Unter(int i) der unterklasse aufgerufen. der aktuelle parameter 15 wird dem formalen parameter als wert zugewiesen.
In diesem konstruktor wird mit dem this-befehl der parameterlose Konstruktor der eigenen Klasse, also Unter(){super100} aufgerufen.
Dieser ruft wiederum mit super-befehl den konstruktor der Oberklasse Ober(int i) auf und weist dem formalen parameter i den wert 100 zu. in diesem konstruktor zeigt die referenzvariable verw vom typ Verwendet auf ein neu erzeugtes Objekt vom typ Verwendet. der formale parameter i dieses objekts bekommt den wert 100 zugewiesen und dieser wird sofort an den konstruktor Verwendet(int i) der Klasse Verwendet weitergeleitet.
und last but not least wird die variable a in diesem konstruktor mit 100 initialisiert.
(ich hoffe ich konnte mich gut ausdrücken). auf jeden fall hat a den wert 100. aber was ist mit b? nun ja, das was ich oben beschrieben habe, war nur der this-teil des konstruktors Unter in der klasse Unter. wir erinnern uns, dass diesem konstruktor zu beginn der wert 15 zugewiesen wurde. und aus dieser 15 wird die zahl 20, da b = i + 5 = 15 + 5.

=> a = 100, b = 20

nun geh ich über zum 2. System.out.println-befehl. um herauszufinden was hier ausgegeben wird, muss ich ja, die v[1] = v[0].kopie(); auswerten.
und genau hier habe ich probleme. also ich weiß, dass ein array auch aus referenzen bestehen kann. sprich: v[0] ruft den konstruktor kopie() der Klasse Unter auf. und wird dieser auf dem feld v[1] zugewiesen? das heißt doch dass auch v[1] auf den konstruktor zeigt, bzw. den konstruktor aufruft. oder? nun ich nehme mal an, dass es stimmt. wird in diesem konstruktor kopie() {return new Unter(this)} ein objekt erzeugt? und was bedeutet das "this" in der klammer?

ich kannte das "this" immer nur im zusammenhang mit referenzen.



ich weiß, dass es viel text, aber ich hoffe, jmd. hilft mir bei dieser analyse. ich möchte zunächst einmal nur wissen, was dieses "this" zu bedeuten hat. mehr brauche ich im moment nicht. vielen dank schon ma im voraus.
 

Bile Demon

Bekanntes Mitglied
wird in diesem konstruktor kopie() {return new Unter(this)} ein objekt erzeugt? und was bedeutet das "this" in der klammer?

Hab das nur mal kurz überflogen. Ein Objekt wird tatsächlich erzeugt. Der parametrisierte Konstruktor Unter(Unter o) erzeugt eben ein Unter-Objekt aus einem anderen Unter-Objekt, aus dem er die Werte kopiert. Der Parameter this ist einfach eine Referenz auf das Objekt, das den Konstruktor aufruft, damit dieser den Inhalt kopieren kann.

Edit: kopie() ist allerdings kein Konstruktor sondern nur eine Methode, die einen Konstruktor aufruft und das erzeugte Objekt zurückgibt,
 
Zuletzt bearbeitet:

paco89

Bekanntes Mitglied
hmmh...okay, das war jetzt zu viel information auf einmal. ich hätte lieber erwähnen sollen, dass ich in sachen JAVA ein anfänger bin. also ich fass mal zusammen was ich bis jetzt verstanden habe:

durch die zuweisung v[1] = v[0].kopie() zeigt jetzt auch v[1] auf die methode kopie() der klasse unter bzw. kann darauf zugreifen und ruft sie auch auf. in dieser methode wird ein neues objekt erzeugt. in den klammer steht als aktueller parameter die this-referenz. die an den konstruktor Unter(Unter o) übergeben wird, wobei this nur eine referenz auf das erzeugte objekt darstellt. so in dem konstruktor Unter(Unter o) wird jetzt wieder mit super(o) der konstruktor der klasse Ober, genauer Ober(Ober o), aufgerufen. dieser bekommt die referenz auf das erzeugte objekt als parameter. durch das o.verw kann ich auf die referenzvariable verw vom Typ Verwendet zugreifen und dieser verweis wird der variablen verw zugewiesen.

und dann? ich versteh irgendwie nicht, welchen wert a am ende haben soll, b hat ja demnach den wert 4...;(((
 

Bile Demon

Bekanntes Mitglied
Kann dir jetzt leider auch nicht aus dem Kopf sagen, welchen Wert a am Ende haben wird, dafür bräuchte ich zu lange. Vielleicht nimmt sich ja jemand die Zeit dafür das mal durchzurechnen.

durch die zuweisung v[1] = v[0].kopie() zeigt jetzt auch v[1] auf die methode kopie() der klasse unter bzw. kann darauf zugreifen

Nach dieser Zuweisung "zeigt" v[1] allerdings nicht auf irgendeine Methode, sondern auf den Rückgabewerte der Methode. In dem Fall ist das ein Klon des Objekts hinter v[0], also ein Unter-Objekt.

Die this-Referenz ist außerdem keine Referenz auf das neu erzeugte Objekt, sondern auf das bereits bestehende Objekt, das diese Objekterzeugung auslöst.
 
M

Marcinek

Gast
Hallo,

ich habe mir das nun auch nicht durgelesen, weil es einfach zu viel ist, aber kann man das nicht laufen lassen und sieht dann, welche Aussgabe kommt?

Mit ein bisschen Übung kann man das auch durchedebuggen, dann sieht man auch warum was ist.

Gruß,

Martin
 

paco89

Bekanntes Mitglied
schade, dann muss ich da wohl alleine durch...ich kann mir zwar immer noch nicht vorstellen, wie das mit dem this funktioniert aber was soll´s....trotzdem danke für die hilfe....
 

paco89

Bekanntes Mitglied
leute, ich habs !!! eigentlich ist es doch so simpel gewesen, wie ich mir das vorgestellt habe....also ich wusste ja zuerst nicht was es mit diesem this auf sich hat. mir war schon klar, dass es bestimmt irgendwas mit ner referenz zu tun hat. aber referenz auf was?
nun ja bile demon hat geschrieben, dass this eine referenz auf das schon existierende objekt ist. so zuerst wusste ich nicht, was damit gemeint ist, aber nach ein paar southpark folgen und 3-4 durchgelsenen abschnittte meines java-buches, kam ich auf die idee.
this zeigt also auf das objekt was wir eine zeile vorher mit new-blabla erzeugt haben, richtig? das this in den klammern ruft die methode Unter(Unter o) auf. weil der eine referenz als formalen parameter hat. die referenzvariable o zeigt nun auch auf dasselbe objekt auf das this auch zeigt. wir können an dieser stelle schonma sagen, dass der wert von b nicht 4 ist, sondern 20. dass das so ist, sieht man an der zuweisung b = o.b. die referenzvariable greift auf das die objektvariable b des alten objekts und weist seinen wert der variablen b zu.

und was ist mit a ? nun ja, verfolgt man den aufruf super(o) so wird doch der konstruktor in der oberklasse aufgerufen, der auch eine referenz als parameter hat. das ist Ober(Ober o). in diesem konstruktor greift die referenzvarriable o auf die vorgerige referenzvariable verw vom typ Verwendet. dieser hatte als a den wert 100.


punkt. ich weiß, ihr mögt nicht so viel text. obwohl es vtl. nicht danach aussieht, habe ich mich bemüht, wenig zu schreiben. ich hoffe, einer macht sich die mühe und liest es. ich mach hier schließlich auch mühe und tippe meine notizen so ausführlich wie möglich ab, nur um zu erfahren, was erfahrenere java-programmierer von meinen ergebnissen halten...


ich mach ma weiter mit dem programm...vtl. beende ich die analyse noch vor sonnenaufgang...
 

paco89

Bekanntes Mitglied
ich habe das mal komipiliert und ausgeben lassen. folgendes erscheint auf der konsole:

v[0] : Unter(Ober(verw = Verwendet(a=100)) , b = 20;
v[1] : Unter(Ober(verw = Verwendet(a=100)) , b = 20;
v[0] : Unter(Ober(verw = Verwendet(a=101)) , b = 19;
v[1] : Unter(Ober(verw = Verwendet(a=101)) , b = 20;
v[0] : Unter(Ober(verw = Verwendet(a=103)) , b = 19;
v[0] : Unter(Ober(verw = Verwendet(a=103)) , b = 18;


ich verstehs aber trotzdem nicht ganz....;((
 

paco89

Bekanntes Mitglied
okay, jetzt ist es schon besser....bis zu den letzten beiden system.out.println-befehlen versteh ich alles....nur warum die letzten beiden system-out-println-befehle 103 und 19 , 103 und 18 ausgeben ist mir noch unklar.....

dafür kann es eigtl nur eine logisch erklärung geben:

kann ich mit dem aufruf v[1].f((short)2) auch die metode void f(int x) aufrufen und dabei x=2 benutzen? denn nur so komm ich auf die 103 und 19, und anschließend auf 103 und 18....
 
M

Marcinek

Gast
Hallo,

die kopie() - Methode erstellt keine tiefe Kopie des Objekts.

Es wird zwar ein neue Unter-Instanz erstellt, diese verwendet "verwendet" der originalklasse, weil hier nur Referenzen kopiert, aber nicht die Werte werden.

Daher geht es da weiter, wo es mit dem vorherigen aufgehört hat.

Schöne Grüße

Martin

P.S. um das korrekt zu machen, müsste nicht super(o) sondern super(o.verwendet.a) gemacht werden.

Das geht aber nicht, weil man hier nicht unterscheiden kann und darf ob man von kopie kommt oder ein neues Objekt erzeugt.
 
Zuletzt bearbeitet von einem Moderator:

paco89

Bekanntes Mitglied
oh, super, danke. ähm...könntest du mir ma bitte kurz sagen/schreiben was genau bei v[1]=v[0].kopie(); passiert? also da wird doch zuerst die rechte seite des gleichheitszeichen abgearbeitet und anschließend dem v[1] zugewiesen, oder ? das heißt, egal wao wir mit v[0].kopie() landen, v[1] zeigt auch darauf, nicht wahr?
 

paco89

Bekanntes Mitglied
jooaaaaaa.....leuteeeeeeeeeeee...ich habs endlich gerafft....nach einem gefühlten jahr hab ich verstanden, warum es so ist, wie es ist....mein problem war, dass ich mir das ganze nicht auf ein blatt papier zeichnen sollte...so kann man es sich am besten vorstellen....und ich hab mir zusätzlich noch das thema "überschreiben von methoden bei der vererbung" reingezogen, was bei dieser aufgabe immens wichtig ist....


trotzdem möchte ich mich bei euch bedanken...dafür, dass ihr mir geholfen habt und (zugegeben) meine manchmal "dummen" zwischenfragen beantwortet habt....


also danke....
 

Neue Themen


Oben