Programmanalyse

hi, ich versuch grad herauszufinden, was der folgende code macht. die aufgabenstellung dazu lautet:

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:


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


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);
  }
}




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);
  }
}




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]);
    System.out.println("v[1] : " + v[1]);
    
    v[0].f(1);
    
    System.out.println("v[0] : " + v[0]);
    System.out.println("v[1] : " + v[1]);
    
    v[1].f((short)2);
    
    System.out.println("v[0] : " + v[0]);
    System.out.println("v[1] : " + v[1]);
    
    
  }
}



ich habe den code mal auf der konsole ausgeben lassen, und dann kommt folgendes raus:

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[1] : Unter(Ober(verw = Verwendet(a=103)) , b = 18;

also bis zun letzten beiden system.out.println-befehlen versteh ich alles…aber danach nichts mehr. was passiert zum beispiel in der zeile in der v[1].f((short)2); steht ?? da ruft doch v[1] die methode f((short)2) der Klasse „Unter“ auf. aber warum haben a=103 und b = 19, und anschließend die werte a = 103 und b = 18 ?

wenn mir das jmd. vtl erklären, was da genau vorgeht, dann wäre ich sehr froh…:wink:

Nein, denn v[1] ist als „Ober“ deklariert. Über diese Referenz kann man ohne Casting keine Methode von „Unter“ aufrufen, außer wenn es sich um eine Überschreibung handelt (was hier nicht der Fall ist). So würde es funktionieren: ((Unter)v[1]).f((short) 2);

Gruß,
André

PS: dem Compiler macht es nichts aus, dass hier ein „short“ statt ein „int“ übergeben wird, weil ein „short“ problemlos als „int“ dargestellt werden kann. Bei einem „float“ wäre das z.B. nicht der Fall und der Compiler würde einen Fehler melden.

ich weiß jetzt warum in den letzten zeilen, das hier:

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

rauskommt. und zwar haben die ja in den zeilen davor v[0].f(1); geschrieben.also zeigt mein v[0] auf die methode f(1) bzw. hat zugriff darauf. verfolgt man anweisungen der funktion f(int x), jetzt aber mit x=2 so erhält man a=103 und b=19. aber wieso bekommt x genau den wert 2 ? aber es muss die 2 als wert haben, sonst kommen wir nicht auf 103 und b=19.

nun zu v[1]. hierbei wird die v[1].f((short)2) aufgerufen. das heißt doch, dass die methode f((short)2) aufgerufen wird. dabei ändert sich der wert von a nicht, jedoch wird b = 18.

ist das richtig so ?

[QUOTE=AndreUhres]

PS: dem Compiler macht es nichts aus, dass hier ein “short” statt ein “int” übergeben wird, weil ein “short” problemlos als “int” dargestellt werden kann. Bei einem “float” wäre das z.B. nicht der Fall und der Compiler würde einen Fehler melden.[/QUOTE]

Genauer erklärt:

Ein ‘short’ passt in einen ‘int’, weil der Wertebereich eines ‘int’ größer ist. Das nennt man eine aufweitende, implizite Konvertierung.

okay, danke…könnt ihr mal sagen, warum auf der konsole die letzten 3 zeilen :

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

gezeigt werden bzw. a und b diese werte annehmen? bei v[1] : Unter(Ober(verw = Verwendet(a=101)) , b = 20; z.b. weiß ich, warum a den wert 101 annimmt, aber warum nimmt b den wert 20 an?
und den rest kann ich mir auch nicht erklären…ich versuche schon seit tagen darauf zu kommen, ich finde allerdings die lösung nicht…;(((

Danke Jango, für die zusätzliche Erläuterung.

„a“ ist ein Attribut der Klasse „Verwendet“, von der nur eine einzige Instanz existiert, die sowohl von v[0] als auch von der Kopie v[1] verwendet wird. „a“ kann darum immer nur einen einzigen Wert haben.

„b“ ist dagegen ein direktes Attribut der Klasse „Unter“, von der ja zwei verschiedene Instanzen existieren: v[0] und v[1]. Bei v[0] wurde „b“ zwar verändert, jedoch nicht bei v[1]. Darum behält es dort seinen ursprünglichen Wert, also 20.

Gruß,
André

ah, okay, vielen dank…jetzt kann ich mir das besser vorstellen. ich möchte nun wieder auf mein v[1].f((short)2) problem zurückkommen. was passiert hier genau? in einem beitrag davor wurde gesagt/geschrieben, dass es dem compiler nichts ausmacht, wenn da in der klammer ein “short” steht.

demnach müsste v[1] doch nicht die methode f(short x), sondern die methode f(int x) aufrufen, oder ?

Richtig. Wir haben dann eine Kopie, bei der das Attribut „verw“ auf das Objekt „Verwenden“ des Originals zeigt. Es wird also keine Kopie des „Verwenden“-Objekts erstellt (das wäre eine sogenannte „tiefe“ Kopie).

    verw = o.verw;
}

Gruß,
André

[QUOTE=paco89]in einem beitrag davor wurde gesagt/geschrieben, dass es dem compiler nichts ausmacht, wenn da in der klammer ein “short” steht.
demnach müsste v[1] doch nicht die methode f(short x), sondern die methode f(int x) aufrufen, oder ?[/QUOTE]

Richtig, die Methode f(short x) wird im Beispiel nie aufgerufen!

Es wäre lieb, wenn Du nicht doppelspurig posten würdest. Also entweder nur hier, oder nur in “java-forum.org

Gruß,
André

ja, sry, aber ich versuch schon seit tagen, den code richtig zu verstehen…und da wollte ich einfach meine chancen verbessern…:wink:

also nochmal zu v[1]. f((short)2). dabei wird doch die 2 explizit in einen „short“ gecastet…aber wir hatten gelernt, dass bei methodenaufrufen immer die spezifischste, bzw. die passendste methode aufgerufen wird. f(short x) passt doch besser, also f(int x) ?das verwirrt mich jetzt…hmmh, also wenn ihr jetzt nicht gewesen wärt, hätte ich sofort f(short x) gedacht…

p.s.: dass mit java-forum.org hab ich schon längst aufgegeben…ich hab zwar vorhin noch n beitrag gepostet, aber da antwortet mir sowieso niemand…

Nein, in der Ober-Klasse gibt es kein f(short x); daher wird diese auch nicht genommen.

Wie André schon geschrieben hat, musst du das dann noch auf die Unterklasse casten.


Komisch, in den java-forum.org Foren sind all deine Fragen beantwortet. Ingesamt zähle ich 4 Threads dazu :wink: :grr:

Ich habe oben bereits geschrieben, dass v[1] als „Ober“ deklariert ist und in „Ober“ gibt es keine f-Methode mit short-Parameter.

Gruß,
André

hmh…

@marcinek: ja sie sind zwar beantwortet, aber ich habe kaum was verstanden…deshalb hab ich hier mein glück versucht…:wink:

[QUOTE=Marcinek]
Komisch, in den java-forum.org Foren sind all deine Fragen beantwortet. Ingesamt zähle ich 4 Threads dazu :wink: :grr:[/QUOTE]

Es steht jedem frei, auch in anderen Foren Fragen zu stellen.

Selbstverständlich steht es jedem frei, allerdings soll man auch wissen: es ist unfair, zeitnah und ohne entsprechende Hinweise in anderen Foren die gleichen Fragen zu stellen ;).

Gruß,
André

jo, leute, das ist kein problem mehr. ich habs endlich verstanden, indem ich mir den ganzen code skizziert habe…mit pfeilen als verweise & Co.

@André Uhres : jo, andré, der grund warum ich kein link zum anderen forum angegeben habe war folgender: ich war mal in einem forum, wo man mathematische fragen stellen konnte. und da habe ich als antwort einen link zu einem anderen mathematischen forum angegeben, wo ich auch registriert war. nachdem ich das gemacht hatte, wurde mein account gesperrt…also ich musste mich neu registrieren etc.

in zukunft werde ich weiterhin bei mehreren foren posten…schließlich sehe ich auch nicht ein, weshalb das ein problem sein sollte. aber ich werde auch meine links zu den anderen foren angeben. keine sorge.

Dann ist es auch in Ordnung, denn in dem Fall muss man nicht seine Zeit verschwenden mit Deinem Problem, wenn es an anderer Stelle bereits gelöst wurde ;).

Gruß,
André