Ausgabe bei Ausführung

Neue Frage »

Auf diesen Beitrag antworten »
neuling96 Ausgabe bei Ausführung

System.out.println(o1.m() + o2.m()); ->(1+2)=(3)
System.out.println(o2.m() + o3.m()); ->(2+2)=(4)

System.out.println(o2.n()); ->2

System.out.println(print(o1)); ->Parameter A: Ich bin ein A.
System.out.println(print(o2));->Parameter B: Ich bin ein B.
System.out.println(print(o3));->Parameter B: Ich bin ein B.

System.out.println(o1.add(o1));2+2= 4
System.out.println(o1.add(o2));geht nicht?
System.out.println(o2.add(o3)); 4+4=8
System.out.println(o2.add(o2));3+3=6
 
Auf diesen Beitrag antworten »
eulerscheZahl

Sei so lieb und gib den Code in Textform und nicht als Bild an, dann kann ich es auch ausführen ohne abtippen zu müssen.
Auf diesen Beitrag antworten »
neuling96

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
public class A {
private int a;
public A(int a){
this.a = a;
}
public int getA(){
return this.a;
}
public int add(A a){
return this.a + a.getA();
}
public int m(){
return 1;
}
public int n(){
return this.m();
}
public String toString(){
return "Ich bin ein A.";
}
}

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
public class B extends A {
private int a;
public B(int a){
super(a);
}
public int getA(){
return this.a;
}
public int add(B b){
return this.getA() + b.getA();
}
public int m(){
return 2;
}
public String toString(){
return "Ich bin ein B.";
}
}

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
public class C {

public static String print(A a){
 return "Parameter A: " + a.toString();
 }

public static String print(B b){
 return "Parameter B: " + b.toString();
 }
 public static void main(String[] args) {

 A o1 = new A(2);
 B o2 = new B(3);
 A o3 = new B(4);

 System.out.println(o1.m() + o2.m());
 System.out.println(o2.m() + o3.m());

 System.out.println(o2.n());

 System.out.println(print(o1));
 System.out.println(print(o2));
 System.out.println(print(o3));

 System.out.println(o1.add(o1));
 System.out.println(o1.add(o2));
 System.out.println(o2.add(o3));
 System.out.println(o2.add(o2));
 }
 }
 }
Auf diesen Beitrag antworten »
eulerscheZahl

Viel besser.
Die erste Unstimmigkeit haben wir hier:
code:
1:
System.out.println(o1.add(o2)); //2

Es gibt die Variablen A.a und B.a.
code:
1:
2:
3:
4:
public B(int a){
    super(a);
    System.out.println("B.a = " + this.a); //Testausgabe liefert: B.a = 0
}

ruft aber den Konstruktor der Elternklasse auf und setzt somit das A.a, währed B.a auf dem Anfangswert 0 bleibt. Bei B.getA() wird daher eine 0 zurückgegeben.
o1.add(o2) macht also 2+0 = 2

code:
1:
System.out.println(o2.add(o3)); //3

Ist ein B.add(A). Da B diese Funktion nicht anbietet (hat nur B.add(B)), wird A.add(A) aufgerufen. this.getA() ist daher 3, b.getA() liefert eine 0 (Begründung siehe oben)

code:
1:
System.out.println(o2.add(o2)); //0

greift zweimal auf B zu, also 0 + 0 = 0.
 
Auf diesen Beitrag antworten »
neuling96

ich sehe gerade, dass in der überschritt des übungsblattes steht : Interface

kann man das verstehen ohne Interface behandelt zuhaben?
Auf diesen Beitrag antworten »
eulerscheZahl

Es geht hier um Vererbung und Polymorphie, um das zu verstehen, musst du keine Interfaces kennen.
Auf diesen Beitrag antworten »
neuling96

ich tun mich das alles nach zuvollziehen
(o1.add(o2));

wieso wird hier
ruft aber den Konstruktor der Elternklasse auf und setzt somit das A.a, aber wieso?

ich verstehe auch nicht wieso es die Variablen A.a und B.a. gibt?
Auf diesen Beitrag antworten »
neuling96

A o3 = new B(4);

was genau macht das?
Auf diesen Beitrag antworten »
eulerscheZahl

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
public class A {
    private int a;
    //...
}

public class B extends A {
    private int a;
    //...
}

die Klassen haben beide eine Variable namens a, aber es sind trotzdem 2 verschiedene Variablen. Dabei verdeckt B.a A.a. Deshalb liefert B.getA() immer 0.

code:
1:
A o3 = new B(4);

legt ein B Objekt an und speichert einen Verweis auf ein A Objekt ab.
Auf diesen Beitrag antworten »
neuling96

legt ein B Objekt an und speichert einen Verweis auf ein A Objekt ab

d.h wenn ich eine Methode mit A o3 = new B(4);
03.beliebigeMethode aufrufe dann wird die beliebigeMethode von B aufgerufen, da es sich um ein Objekt aus B handelt?


wird hingegen

haben wir public int(A a) und public int(B b), dann wird public int(A a) ausgeführt?
Auf diesen Beitrag antworten »
eulerscheZahl

Zitat:
haben wir public int add(A a) und public int add(B b), dann wird public int add(A a) ausgeführt?

Bei o2.add(o3) wird o2.add(B b) aufgerufen, da o3 ein B ist. o3 verhält sich wie ein B.
Einen Unterschied gibt es aber: die main kennt o3 als A und erlaubt daher nur, dessen Funktionen aufzurufen.

code:
1:
System.out.println(o3.add(o2)); //4

ruft die Funktion add der Klasse A auf, da o3 in der main als A und nicht als B bekannt ist.
Mein Rat: hole dir NetBeans/eclipse und gehe das Programm mit Hilfe des Debuggers Zeile für Zeile durch, dann siehst du, wann welche Funktion aufgerufen wird.
Auf diesen Beitrag antworten »
neuling96

Zitat:
Original von eulerscheZahl
System.out.println(o2.add(o3)); //3
Ist ein B.add(A). Da B diese Funktion nicht anbietet (hat nur B.add(B)), wird A.add(A) aufgerufen. this.getA() ist daher 3, b.getA() liefert eine 0

.


Zitat:
Original von eulerscheZahl
Zitat:
haben wir public int add(A a) und public int add(B b), dann wird public int add(A a) ausgeführt?

Bei o2.add(o3) wird o2.add(B b) aufgerufen, da o3 ein B ist. o3 verhält sich wie ein B.
Einen Unterschied gibt es aber: die main kennt o3 als A und erlaubt daher nur, dessen Funktionen aufzurufen.

.



wieso ist einmal B.add(A). und dann B.add(B)

und was genau ist die main im Programm?
Auf diesen Beitrag antworten »
eulerscheZahl

das ist die main:
code:
1:
public static void main(String[] args) {


Ich tue mir gerade schwer, wie ich das erklären soll, hilft dir das weiter? Javainsel
Auf diesen Beitrag antworten »
neuling96

o1.add(o2)

das problem was ich habe ist folgendes
01 ist von A und damit o1.add(o2) auf etwas zugegriffen, was eig nicht in der klasse A gibt


System.out.println(o2.add(o2)); //0
das habe ich verstanden

System.out.println(print(o3));

die main nimmt es als 03 als A auf

also wird
public static String print(A a){
return "Parameter A: " + a.toString();
}
aus geführt?

bei a.toString wird aber aber auf B klasse zugegriffen


also

Paramerter A: ich bin ein B
Auf diesen Beitrag antworten »
eulerscheZahl

[qoute]o1 ist von A und damit o1.add(o2) auf etwas zugegriffen, was eig nicht in der klasse A gibt [/quote]
aber o2 ist ja als B nichts anderes als ein abgeleitetes A. Daher kann es verwendet werden (wenn es in A eine Funktion add(B) geben würde, würde die genommen werden. Gibt es aber nicht, also die zweitbeste Lösung, die ein A erwartet.

toString() gibt es für 2 Klassen (eigentlich für 3, auch für Object, von dem A erbt). o3 ist von Typ B, ruft also B.toString() auf.
Hätte B noch eine Funktion, die A nicht besitzt, könntest du sie in der main nicht aufrufen, da o3 dort als A deklariert ist.
Auf diesen Beitrag antworten »
neuling96

wie nimmt das allg Prinzip das hinter diesen Prozess steht?
Auf diesen Beitrag antworten »
eulerscheZahl

Das nennt sich Polymorphie.
Auf diesen Beitrag antworten »
neuling96

[quote]Original von eulerscheZahl
Viel besser.
Die erste Unstimmigkeit haben wir hier:
code:
1:
System.out.println(o1.add(o2)); //2

Es gibt die Variablen A.a und B.a.
code:
1:
2:
3:
4:
public B(int a){
    super(a);
    System.out.println("B.a = " + this.a); //Testausgabe liefert: B.a = 0
}

ruft aber den Konstruktor der Elternklasse auf und setzt somit das A.a, währed B.a auf dem Anfangswert 0 bleibt. Bei B.getA() wird daher eine 0 zurückgegeben.
o1.add(o2) macht also 2+0 = 2
[quote]


"Bei Attributen tritt dabei der Effekt der
Versteckens
auf: Das Attribut der
Vaterklasse ist in der abgeleiteten Klasse nicht mehr sichtbar"

genau das haben wir hier vorliegen, auf das Attribute this.a ist nicht mehr sichtbar in der Vaterklasse.


muss in der abgeleiteten klasse

Es ist nicht erlaubt, den Default-Konstruktor aufzurufen, obwohl
ein expliziter Konstruktor in der Vaterklasse vorhanden ist und der
Default-Konstruktor nicht existiert

was wenn in der vaterklasse

public class A {
private int a;
public A(){ // ohne in klammern int a
this.a = a;
}

und muss eine abgeleitet klasse stets mit super beginnen also ich mein

public class B extends A {
private int a;
public B(int a){
super(a);// ohne super obwohl in der vaterklasse ein -Konstruktor vorhanden ist
}
Auf diesen Beitrag antworten »
neuling96

"Bei Attributen tritt dabei der Effekt der
Versteckens
auf: Das Attribut der
Vaterklasse ist in der abgeleiteten Klasse nicht mehr sichtbar"

genau das haben wir hier vorliegen, auf das Attribute this.a ist nicht mehr sichtbar in der Vaterklasse.

und deshalb ist this.a nicht mehr sichtbar in B ??
Auf diesen Beitrag antworten »
eulerscheZahl

zum Verstecken: ja, genau das ist der Fall. Aber this.a ist weiterhin vorhanden - nur einen ein anderes a. Nämlich das der Kindklasse.

Zitat:
public class A {
private int a;
public A(){ // ohne in klammern int a
this.a = a;
}

wenn kein a an die Funktion übergeben wird, dann ist this.a nur eine andere Schreibweise für a. Und da der Initialwert (und somit aktuelle Wert) 0 ist, setzt du ihn erneut zu 0.


super(a) ruft den Konstruktor der Elternklasse auf. Das ist nicht verpflichtend, kommt eben darauf an, welches Verhalten du erzielen willst.
Auf diesen Beitrag antworten »
neuling96

Zitat:
Original von eulerscheZahl
zum Verstecken: ja, genau das ist der Fall. Aber this.a ist weiterhin vorhanden - nur einen ein anderes a. Nämlich das der Kindklasse.



und der einzige zugriff this.a erfolgt durch den befehl super, richtig?
Auf diesen Beitrag antworten »
eulerscheZahl

Ja, das ursprüngliche a kriegst du nur über super.a - oder besser gesagt über super.getA(), da a ja private ist.
Auf diesen Beitrag antworten »
neuling96

noch eins
das in der klasse A def funktion
public int getA(){
return this.a;

kann nun jede beliebig klasse zugriffen werden mit super.getA()?
Auf diesen Beitrag antworten »
eulerscheZahl

Wenn Klasse B von A erbt, kannst du mit super.getA() darauf zugreifen.
Wenn Klasse C von B erbt und B und C ebenfalls ein getA() haben, wirst du an A.getA() nicht mehr herankommen. Ein super.super gibt es nicht.

Außerhalb der Klasse geht das auch nicht: B b = new B(2); b.super.getA(); geht also auch nicht.
Auf diesen Beitrag antworten »
neuling96

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
public class A {
private int a;
public A(int a){
this.a = a;
}
public int getA(){
return this.a;
}
public int add(A a){
return this.a + a.getA();
}
public int m(){
return 1;
}
public int n(){
return this.m();
}
public String toString(){
return "Ich bin ein A.";
}
}

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
public class B extends A {
private int a;
public B(int a){
super(a);
}
public int getA(){
return this.a;
}
public int add(B b){
return this.getA() + b.getA();
}
public int m(){
return 2;
}
public int n() {
return this.m();
}
public String toString(){
return "Ich bin ein B.";
}
}

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
public class C {

public static String print(A a){
 return "Parameter A: " + a.toString();
 }

public static String print(B b){
 return "Parameter B: " + b.toString();
 }
 public static void main(String[] args) {

 A o1 = new A(2);
 B o2 = new B(3);
 A o3 = new B(4);



 System.out.println(o3.n());


 }
 }
 }


bestimme den wert von o3.n()
o3.n() ist =2 (überschreiben effekt)

jetzt soll die Methode int n() von A ausgeklammert werden
was liefert nun o3.n()

die main kennt o3 als A, allerdings wird erst zur lauzeit entscheiden, welche methode ausgeführt, aber in A gibt es int n () nicht mehr

ich denke
der Compiler überprüft vor der laufzeit ob überhaupt die Methode enthalten ist?? (ist geraten)
und damit geht es nicht, weil int n() nicht in A gibt??
Auf diesen Beitrag antworten »
eulerscheZahl

Der Compiler stellt zwar fest, ob A die Methode n() hat, weshalb sich das Programm auch nicht starten lässt. Aber mit Laufzeit hat das nichts zu tun (das ist auch nicht Aufgabe des Compilers, sonst könntest du dir Laufzeitfehler ja auch schon beim Compilieren anzeigen lassen).
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »