Klausuraufgaben

G

ge0rg

Gast
Hi Leute! Ich und meine Kommilitonen bereiten uns im Moment auf eine Informatik-Präsenzübung vor, also so eine Art Klausur. Wir haben heute mal die erste Aufgabe dieser Klausur vorgenommen und...naja, sind kläglich gescheitert ;) Zwar war das meiste, was wir zunächst raus hatten sogar richtig, jedoch mussten wir im nachhinein unsere Überlegungen stark in Frage stellen. Aber erstmal der Code.
Java:
public class A {
public int x=1;

public A(){
this(5);}

public A(double d){
this((int)d/3);
}

public A(int i){
x+=i;
}

public void f(double z){
this.x+=x+1;
}
}

public class B extends A{
public int y=5;

public void f(double x){
this.x+=x;
y++;
}

public void f(int x){
y=0;
}
}

public class M{
public static void main(String[]args){
A a=new a(7.0);
System.out.println(a.x); // was wird rausgegeben?
a.f(10);
System.out.println(a.x);// wie oben
B b = new B();
System.out.println(a.x+" "+b.y);//w.o
b.f(10.0);
System.out.println(b.x+" "+b.y);//w.o
a=b;
a.f(1.0);
System.out.println(a.x+" "+b.x);//w.o
a.f(2);
System.out.println(ax+" "+by);//w.o
}

}

Es sei noch gesagt, dass die meisten von uns zwar vorher schon meist rudimentär programmiert haben, aber eher wenig als viel...

So, hier usere/meine überlegungen:
Als erstes wird der 2. Konstruktor aus A aufgerufen. Die 7 wird auf int gecastet und durch 3 geteilt, gibt 2. Dann wird durch das this der Konsturuktor aufgerufen, auf das 2 als int passt, also der dritte (ist das korrekt so? wenn nicht, was ist die fachlich richtige begründung? was genau tut das this hier?).
Der addiert auf das x die 2, also ist a.x=3, was auch rausgegeben wird und laut Musterlösung richtig ist.

a.x=3

Als nächstes wird a.f mit 10 aufgerufen. Die 10 wird nacg double gecastet, was aber unerheblich ist. Die Funktion macht im Grunde x=2x+1, kommt also 7 raus, was laut Musterlösung ebenfalls stimmt. Also:

a.x=7

Als nächstes wird eine neue Instanz von B erstellt, was a.x nicht beeinflusst, b.y ist=5. Laut Musterlösung ebenfalls korrekt.

a.x=7 b.y=5
Außerdem wird noch der Standardkonstruktor von A aufgerufen, der x von 1 auf 6 setzt. Das haben wir auch nicht sofort gewusst, leider. Deshalb: Warum genau ist das so, und ist das so richtig? Demnach wäre außerdem: b.x=6.

Jetzt wird die void f- Funktion aus B aufgerufen. Auf das b.x wird die 10 aufaddiert, also ist b.x=16, das b.y um eins erhöht, also b.y=6. Laut Musterlösung auch richtig.

a.x=7, b.x=16, b.y=6

Anschließend referenziert a das Objekt, was von b referenziert wurde. Darüber würde ich gerne alles wissen ;). Inzwischen, und das hat gedauert, haben wir rausgefunden, dass a immernoch eine Referenz vom Typ A, und b vom Typ b bleibt. (Denn a.y existiert nicht...). Wie verhält sich das "neue" a jetzt bei Funktionsaufrufen, welche Funktionen welche Klassen werden wann aufgerufen? Hier hatten wir Probleme.
Klar, erstmal ist a.x=b.x=16. Aber welche Funktion wird dann aufgerufen? Eigentlich doch eine aus A, oder? Da käme ja nur eine in Frage, das Ergebnis wäre a.x=b.x=33, was nach musterlösung falsch ist (Kollege hats aber auch kompiliert und für jeden schritt geprüft. Rauskommen müsste a.x=b.x=17. Da kommt nur f aus B in Frage, die das tut. Was haben wir hier falsch gedacht?
Außerdem gilt y++, also:

a.x=b.x=17, b.y= 7

a.f(2) wird aufgerufen. Hier wieder die Frage, welches f wird aufgerufen? Ich würde ja auf das aus A tippen, dann wird (int)2 nach double gecastet. Dann kommt aber a.x=25 raus, richtig wäre 19...
Das wäre das, was f aus B tun würde, aber warum wird diese aufgerufen dann? weil 2 ein int ist?
y++, dann wäre b.y=8, was auch stimmt, also:

a.x=19, b.x=19, b.y=8

Ich wäre an dieser Stelle dankbar, wenn mir jemand diese Verwirrungen aufklären könnte. Danke
Georg
 
Zuletzt bearbeitet von einem Moderator:

Hemme

Mitglied
Boah, der Code ist für mich rein optisch recht verwirrend..

Da hats zwei Klassen drin die public sind, wenn du die trennen könntest, würde das der Übersicht schon mal sehr viel helfen..


Java:
public void f(double z){
   this.x+=x+1;

}

Wieso gibtst du eine Zahl mit, wenn du sie gar nicht brauchst??
 
Zuletzt bearbeitet:
S

SlaterB

Gast
der Code läßt sich gar nicht kompilieren, gehört wohl alles mit zur Aufgabe

zu Hause kann man das doch wenigstens dem Compiler übergeben, der weist schon auf ein paar Missstände hin
 
G

ge0rg

Gast
Also, ich habe die Aufgabe aus der Pdf abgetippt. Es wäre natürlich denkbar, dass sich irgendwo ein tippfehler eingeschlichen hat.
Ich könnte also am Code schonmal nichts rütteln, also keine Klassen trennen etc, weil es so vorgeschrieben ist.
Mein Kommilitone hat das vorhin auf seinem Laptop abgetippt (jede Klasse auch einzeln) und da gings, also wenn, dann liegt der Fehler bei mir.
Aber: Die Aufgabe soll gar nicht mit Compiler gelöst werden, von daher...Was tatsächlich rausgegeben wird, kann ich euch auch so sagen:
3
7
7, 5
16, 6
17,17
19,8
 
G

ge0rg

Gast
Also, um es nochmal klarzumachen: Der Code ist NICHT von mir, sondern aus einer Art probeklausur(die von letztem jahr...). Ich kann/darf da nichts ändern, von eventuellen tippfehlern, die beim abschreiben passiert sind mal abgesehn. Alles, was ist tun soll, ist vorraussagen, was die konsole am ende rausgibt.
 
S

SlaterB

Gast
> this der Konsturuktor aufgerufen, auf das 2 als int passt, also der dritte (ist das korrekt so?

ja

> was ist die fachlich richtige begründung? was genau tut das this hier?

ruft einen passenden Konstruktor auf

> Das haben wir auch nicht sofort gewusst, leider. Deshalb: Warum genau ist das so, und ist das so richtig?

ist einfach so, merken kann man sich: jedes erstelle Objekt durchläuft mindestens einen Konstruktor,
notfalls den ohne Parameter,
bei Vererbung gilt auch für alle Super-Klassen, dass einer durchlaufen werden muss

> Aber welche Funktion wird dann aufgerufen? Eigentlich doch eine aus A, oder?

durch die statische Verlinkung schaut sich der Compiler an, welche Methode von A am besten passt, die mit dem double-Parameter,
jetzt ist die Signatur f(double) festgelegt,
zur Laufzeit wird dann aber dynamisch geprüft von welchem Typ das Objekt in der A-Variable tatsächlich ist,
es ist B und B überschreibt exakt diese Methode, damit kommt B dran,

interessant wäre folgendes:
A hat eine Methode
> public void add(A other);

B hat eine Methode
> public void add(B other);


B b = ..;
A a = b;
a.add(b);

a ist zur Laufzeit vom Typ B, dort gibt es add(B), man könnte meinen das wäre die perfekte Methode,
bei b.add(b) wird sie auch verwendet

bei a.add(b); gilt aber wieder: der Compiler kann zum Zeitpunkt des Kompilierens nur aus den Methoden von A wählen,
also ist festgelegt, dass eine Methde add(A) drankommt,

B überschreibt add(A) nicht, deshalb wird die Methode von A ausgeführt,
add(B) in B ist was anderes als add(A),
nur wenn exakt die richtige Methode überschrieben wird, kann diese zur Laufzeit 'dazwischenfunken'




> Das wäre das, was f aus B tun würde, aber warum wird diese aufgerufen dann? weil 2 ein int ist?

genau derselbe Fall
 
Zuletzt bearbeitet von einem Moderator:
Ähnliche Java Themen

Ähnliche Java Themen


Oben