Frage zu Überladung und Subtyping

Status
Nicht offen für weitere Antworten.

siebeck

Mitglied
Hallo,

habe folgendes Problem bei diesem Programm:

Code:
class A {
    void m(A a) {System.out.println("1");  //Zeile 1
    }
class B extends A {
    void m(A a)  {System.out.println("2"); //Zeile 2
    void m(B a)  {System.out.println("3"); //Zeile 3
    }
class Test {
	public static void main(String[] args) {
		B b=new B();
		A a=b; 		
		a.m(a);
		a.m(b);
		b.m(a);
		b.m(b);
}

Hier folgt die Ausgabe
2
2
2
3

Die in Zeile 1 dekl. Methode wird in Subklasse B durch die Zeile 2 überschrieben.
In KLasse B ist m (A a) überladen durch die Methode m( B b).
Zur Übersetzungszeit werden die beiden Methodenaufrufe a.m(a) und a.m(b) an die in Zeile 1 deklarierte Methode gebunden.
Weil Variable a zur Laufzeit ein B-Objekt enthält, wird wegen der dynamischen Methodenauswahl die sie überschreibende Methode der Klasse B ausgeführt, also 2mal "2" ausgegeben.

So stehts in der Erläuterung! Dieser letzte Satz verstehe ich nicht. Zur Laufzeit enthält die Variable a ein B-Objekt, soweit klar. Bei a.m(a) wird 2 ausgegeben, auch klar. Aber müßte bei a.m(b) nicht 3 ausgegeben werden?

[Edit by Beni: Codetags eingefügt]
 

André Uhres

Top Contributor
a ist ja eigentlich vom Typ A, und Typ A kennt kein "void m(B a) {..}"
Du kannst es leicht überprüfen:
Wenn du in Klasse A einen "void m(B a) {..}" reintust, dann kommt 3.
 
G

Guest

Gast
siebeck hat gesagt.:
Zur Laufzeit enthält die Variable a ein B-Objekt, soweit klar. Bei a.m(a) wird 2 ausgegeben, auch klar. Aber müßte bei a.m(b) nicht 3 ausgegeben werden?

HI, ich glaube so ganz klar ist dir das mit dem B-Objekt enthalten noch nicht. B ist eine Erweiterung von A (siehe extends Direktive). Das heißt, dass ein B alles kann was ein A kann (und ggf. mehr).
Eine Zeile wie
Code:
A a = new B();
Legt eine Variable a vom Typ A an. Dass heißt für Java nur, dass dieses a alle Eigenschaften von A haben muss. Eine Erweiterung von diesem A um weitere Variablen, mit weiteren Methoden kann dabei verwendet werden. Aber auf diese hast du keinen Zugriff:

Code:
class A {
  public void doFoo1() {
  ...
  }
}

class B extends A {
  public void doFoo2() {
  ...
  }
}

public class Main {
  public static void main(String[] args) {
    A a = new B();
    B b = new B();

    b.doFoo1(); // möglich, da von A geerbt / A erweitert
    b.doFoo2(); // möglich da b vom Typ B
    
    a.doFoo1(); // möglich da vom Typ A
    a.doFoo2(); // nicht möglich! Variable ist vom Typ A und kennt nur die Eigenschaften von A
    ((B)a).doFoo2(); // möglich da explizit gecastet
  } 
}

Das zu verstehen ist eine wichtige Grundlage für die OOP. Du wirst später noch auf Interfaces und abstrakte Klassen stossen. Diese eignen sich für eine solche Vorgehensweise immer besonders gut. Du hast dann nur eine abstrakte Struktur. In Interfaces sind zum Beispiel nur die öffentlichen Methoden bekannt. Das zugewiesene Objekt ist damit völlig austauschbar.

[Edit by Beni: Codetags repariert]
 

Revenant

Aktives Mitglied
Hi,

muss mich mal mit ner Frage in den Thread einklinken. Ich hätte nicht gedacht, dass sowas wie

Code:
A a = new B();

überhaupt möglich ist! Auf der linken Seite wird ja eine Variable a vom Typ A angelegt, und dann wird ihr (auf der rechten Seite) eine Instanz der Klasse B zugewiesen?! Das geht dann aber nur, wenn B von A abgeleitet ist oder??

Und noch ne Frage: wenn ich in einer Klasse keinen Konstruktor angebe, was für ein Konstruktor (mit welcher Implementierung) wird dann aufgerufen? Es ist ja immer die Rede von diesem "Standartkonstruktor" aber wie sieht der konkret aus?
 

gekkonier

Mitglied
Nackig ist der Konstruktor dann, oder er wird von einer beerbeten Klasse weiterverwendet, wenn er dort überschrieben worden ist denk ich mal.

Warum
Code:
A a = new B();
funktioniert kann ich mir auch nicht wirklich erklären ???:L
 

Leroy42

Top Contributor
Ganz einfach, weil jedes B auch zugleich ein A ist.

Code:
class Tier {}
class TierMitZweiOhren extends Tier{}

Tier[] vieleBunteTiere = {new Tier(), new TierMitZweiOhren()};
vieleBunteTiere kann eben alle Tiere aufnehmen, auch die abgeleiteten, spezielleren.


Code:
TierMitZweiOhren tier = new Tier();

geht dann natürlich nicht, da nicht jedes Tier eins mit 2 Ohren ist.

Verständlicher? ???:L :autsch:
 
G

Guest

Gast
Hi,
in meinem Beispiel von vorhin erbt doch B auch von A. Der Begriff der Vererbung ist hier einfach nur schlecht gewählt. Ich denke intuitiver ist weiterhin der Begriff erweitern. Natürlich ist beides hier das Gleiche.
Was wichtig ist, B ist ein spezielleres A. A hat die Methode doFoo1(). B erweitert A, hat also auch schon mal eine Methode namens doFoo1(). B kann diese Methode jetzt überschreiben oder eben nicht.
Soweit so gut. B erweitert jetzt die Klasse A um eine weitere Methode doFoo2(). Diese Methode hat nur B. A weiß gar nicht, dass es eine solche Methode gibt (und das interessiert A auch gar nicht).
Wenn ich jetzt ein A möchte, dann heißt dass nur, dass ich eine Klasse möchte, die die Funktion doFoo1(); anbietet. Wie diese Methode eigentlich implementiert ist, dass ist mir egal.

Wie gesagt, richtig deutlich wird so etwas wenn man Interfaces betrachtet. Diese sind abstrakt, es kann keine direkte Instanz von einem Interface geben. Was es gibt sind nur Instanzen von Klassen, die dieses Interface implementieren. Wozu also ein Interface?
Die Idee ist eigentlich ganz einfach. Implementiert eine Klasse ein Interface oder erbt sie von einer anderen, ist es einfach nur eine Zusicherung, dass eine bestimmte Methode existiert.
Ein sehr einfaches Interface ist Comparable. Es bietet einfach nur die Möglichkeit zwei Elemente miteinander zu vergleichen. Es wird -1, 1 oder 0 geliefert (für kleiner, größer oder gleich).
Entwickelt man jetzt einen Sortieralgorithmus der super schnell und super toll ist, so möchte man wohl alles damit sortieren. Man hat nun zwei Möglichkeiten.
Die erste Möglichkeit wäre es für jede Klasse die man sortieren möchte eine eigene Variante zu schreiben (viel Spaß!). Das kostet viel Zeit, führt leicht zu fehlern und wenn man dann einen noch tolleren Sortieralgorithmus findet war alles für den ...
Die andere Möglichkeit ist es, dass man einfach das Comparable Interface verwendet. Hat man zwei Instanzen einer Klasse die dieses Interface implementiert, weiß man zwar nicht wie diese Instanzen verglichen werden, aber man weiß dass die Methode compare() existiert. Diese vergleicht (ohne das wir wissen wie) und sagt ob das erste Element kleiner, größer oder gleich ist. Mehr wollen wir gar nicht wissen, ist super!

Ein kleines Beispiel anhand der Maximum Funktion. Ist zwar kein Sortieralgo, aber bin gerade zu faul einen aufzuschreiben:

Code:
// einfaches Suchen eines Maximum in einem Array
// Version 1

Integer findMax(Integer[] i) {
  Integer res = null;

  if (i.length > 0) {
    res = i[0];

    for (int j = 0; j < i.length; j++) {
      if (res.intValue() < i[j].intValue()) {
        res = i[j];
      }
    }
  }

  return res;
} 

Byte findMax(Byte[] b) {
  Byte res = null;

  if (b.length > 0) {
    res = b[0];

    for (int j = 0; j < b.length; j++) {
      if (res.intValue() < b[j].intValue()) {
        res = b[j];
      }
    }
  }

  return res;
} 

// und noch für jede andere Klasse so weiter...
// findet man nun einen besseren Weg darf man von vorne beginnen

// Version 2
Comparable findMax(Comparable[] c) {
  Comparable res = null;

  if (c.length > 0) {
    res = c[0];

    for (int j = 0; j < c.length; j++) {
      if (res.compareTo(c[i])) {  // wie die Methode heißt hab ich gerade nicht im Kopf, glaube compare oder compareTo
        res = c[j];
      }
    }
  }

  return c;
}

// das ganze kann man noch etwas schöner mit Generics machen, hier gibt es dann auch die Zusicherung und man muss nicht noch casten!

So, der Unterschied sollte grob klar sein. In Version 2 habe ich diese eine Methode, die für alle Instanzen verwendet werden kann, die das Interface Comparable implementieren. Die Wrapper Integer, Short, ... gehörten natürlich dazu. Vom Interface Comparable gibt es aber trotzdem keine Instanzen.
Code:
Comparable c;
c = new Comparable(); // geht nicht! Comparable ist nur ein Interface!
c = new Integer(); // geht, da Integer implements Comparable gilt

Das gleiche hat man dann halt mit Klassen und Vererbung. Der Typ einer Variablen sichert eben nur die Eigenschaften dieses Typs zu. Wird ein Instanz zugewiesen die spezieller ist (mehr kann, etwas auf eine bestimmte Art und Weise macht), so ist das egal.
Das Maximum eines Arrays ist größer als jeder andere Wert im Array. Ob größer dabei heißt, dass es eine größere Zahl, ein höheres Datum, eine spätere Zeit, .... ist ist egal!
 

Lim_Dul

Top Contributor
Revenant hat gesagt.:
Hi,

muss mich mal mit ner Frage in den Thread einklinken. Ich hätte nicht gedacht, dass sowas wie

Code:
A a = new B();

überhaupt möglich ist! Auf der linken Seite wird ja eine Variable a vom Typ A angelegt, und dann wird ihr (auf der rechten Seite) eine Instanz der Klasse B zugewiesen?! Das geht dann aber nur, wenn B von A abgeleitet ist oder??

Und noch ne Frage: wenn ich in einer Klasse keinen Konstruktor angebe, was für ein Konstruktor (mit welcher Implementierung) wird dann aufgerufen? Es ist ja immer die Rede von diesem "Standartkonstruktor" aber wie sieht der konkret aus?

Richtig, der Code geht nur, wenn B von A abgeleitet ist.

Ist B aber auch:
Code:
class B extends A {

Der Standardkonstruktor ist der Konstruktor ohne Parameter.
Wenn man in der Klasse garkeinen Konstruktor angibt, wird implizit einer erzeugt, der einfach nichts macht.

Also einer der Form:

Code:
public A() {}
 

Acha

Bekanntes Mitglied
Hi,

muss mich mal mit ner Frage in den Thread einklinken. Ich hätte nicht gedacht, dass sowas wie



Code:
A a = new B();




überhaupt möglich ist! Auf der linken Seite wird ja eine Variable a vom Typ A angelegt, und dann wird ihr (auf der rechten Seite) eine Instanz der Klasse B zugewiesen?! Das geht dann aber nur, wenn B von A abgeleitet ist oder??

Sowas nennt man bei Java Polymorphie, falls das jemand nachlesen will!

MFG

Acha
 

siebeck

Mitglied
André Uhres hat gesagt.:
a ist ja eigentlich vom Typ A, und Typ A kennt kein "void m(B a) {..}"
Du kannst es leicht überprüfen:
Wenn du in Klasse A einen "void m(B a) {..}" reintust, dann kommt 3.

Vieles ist mir einleuchtend.
Ich glaub aber, ich komme mit der Schreibweise void m(B a) nicht so ganz zurecht.
a heißt, das es vom Typ A ist, und was heiß das große B in void?

wenn a.m(b) aufgerufen wird,heißt das doch, das von der Klasse A die Variable b gewünscht wird. Diese gibt es in meiner Ausführung nicht. Also wird die überschreibene Methode aufgerufen: void m (A a) und 2 (Zeile 2) ausgegeben. Warum wird nicht die überladene Methode ausgeführt und Zeile 3 ausgegeben? Schließlich ist im Aufruf a.m(b) in Zeile 3 void m(B b) b enthalten?

Den Tip von Andre Uhres habe ich ausprobiert.
Kann man das dann so interpretieren:
Bei Aufruf von a.m(b) wird die Methode von der Klasse A void m(B a) aufgerufen, da aber B von A erbt und durch A a=b wird die Methode in Klasse B durch void m(B b) überschrieben und damit Zeile 3 ausgegeben.
Liege ich damit richtig?
 

Leroy42

Top Contributor
:shock:
Du solltest dringend Einführungskapitel eine Java-Buchs durcharbeiten.

Ich glaub aber, ich komme mit der Schreibweise void m(B a) nicht so ganz zurecht.
a heißt, das es vom Typ A ist, und was heiß das große B in void?


Nein! Es gibt die Methode des Namens m die nichts zurückliefert (void) und einen
Parameter übergeben bekommt. Dieser Parameter wird innerhalb der Methode a
genannt und muß vom Typ (eine Instanz der Klasse) B sein.

...

alle weiteren Fragen überblicke ich im Moment nicht. :autsch:
 

Lim_Dul

Top Contributor
Insbesondere solltest du dich mit einfacheren Beispielen beschäftigen, als mit solchen hier, die gleich zwei Konzepte miteinander vermengen und "Seiteneffekte" beobachten.
 

siebeck

Mitglied
Danke für die Antworten.

Habe da eher das Problem, das ich an der Fernuni Hagen studiere, und dieses Fach im 2 Monaten Verspätung begonnen habe.

Um am Samstag schreibe ich die Klausur!

Trotzdem danke für die Antworten.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Frage zur Vererbung/Überladung Java Basics - Anfänger-Themen 3
J Frage zum Quellcode - Zusammhänge und Ablauf. Java Basics - Anfänger-Themen 2
D Erste Schritte Frage eines absoluten Anfängers Java Basics - Anfänger-Themen 3
Zrebna Frage zu Test-Driven Development (TDD) Java Basics - Anfänger-Themen 3
I Frage Thymeleaf -> Fehler ignorieren und mit "" ersetzen? Java Basics - Anfänger-Themen 15
I Frage Thymeleaf -> Prefix / Suffix ändern? Java Basics - Anfänger-Themen 11
D Rekursions Probleme / frage Java Basics - Anfänger-Themen 4
T Frage zu Parse Java Basics - Anfänger-Themen 2
H Frage an die Profis Java Basics - Anfänger-Themen 4
J Eine konzeptionelle Frage zu OOP Java Basics - Anfänger-Themen 3
P Frage zu Rekursion und Backtracking Java Basics - Anfänger-Themen 2
H Frage zur Ausgabe Java Basics - Anfänger-Themen 4
H Frage zu arithmetischen Operationen Java Basics - Anfänger-Themen 20
F Kurze Frage zu replace() Java Basics - Anfänger-Themen 19
JavaSchmecktLecker Polymorphie Frage zur Methodenüberschreibung Java Basics - Anfänger-Themen 21
J Frage zu einem "Taschenrechner" code Java Basics - Anfänger-Themen 9
B Erste Schritte Frage zu Instanzierung und Referenzen Java Basics - Anfänger-Themen 8
DoubleM Runtime.getRuntime().exec Frage Java Basics - Anfänger-Themen 2
J Eine theoretische Frage zur Praxis - JPanel oder Canvas Java Basics - Anfänger-Themen 5
O Frage: Formaler Typbezeichner? Java Basics - Anfänger-Themen 3
I BlueJ Queue Frage für Klausur Java Basics - Anfänger-Themen 2
N Verständnis Frage zu Variablen Java Basics - Anfänger-Themen 3
N Spezielle frage zum Comparator Java Basics - Anfänger-Themen 6
L Frage zum Array Java Basics - Anfänger-Themen 1
A Frage zum UML Design Java Basics - Anfänger-Themen 1
I Hilfe bei Klausur Frage Java Basics - Anfänger-Themen 8
izoards Drucken Frage zu FAQ Beitrag Java Basics - Anfänger-Themen 2
J Frage zu meinem Code (OOP) Java Basics - Anfänger-Themen 4
sserio Split() -> Regex Frage. Java Basics - Anfänger-Themen 7
A OCA Study Guide: 2. Frage aus Kapitel 3 Java Basics - Anfänger-Themen 9
sserio Date Library Frage Java Basics - Anfänger-Themen 9
Max246Sch Frage zu Währungsrechner Code Java Basics - Anfänger-Themen 2
sserio Frage zu HashMaps Java Basics - Anfänger-Themen 20
sserio Frage zu Threading - Multithreading Java Basics - Anfänger-Themen 2
sserio Frage zu Lambda Ausdrücken Java Basics - Anfänger-Themen 7
sserio Frage zu BigInteger Java Basics - Anfänger-Themen 1
D Frage bzgl. Enum-Handhabung Java Basics - Anfänger-Themen 16
xxx12 Frage Java Basics - Anfänger-Themen 2
I Generelle Frage zu Mikroservices (Spring Boot?), Docker... Java Basics - Anfänger-Themen 7
R Frage zu Methoden (Rückgabewert u. ohne.) Java Basics - Anfänger-Themen 2
A Frage zur programmierung Java Basics - Anfänger-Themen 12
M Frage zur Methode split der Klasse String Java Basics - Anfänger-Themen 32
R Input/Output Frage zu Java IO Java Basics - Anfänger-Themen 6
M Frage zu printWriter Java Basics - Anfänger-Themen 5
C Frage zu OLSMultipleLinearRegression Java Basics - Anfänger-Themen 31
KogoroMori21 Frage zum Euklidischen Algorithmus Java Basics - Anfänger-Themen 11
S Verständnis-Frage zu einer HÜ? Java Basics - Anfänger-Themen 1
F Frage betreff Programm mit dem man C++-Code in JAVA-Code übersetzen lassen kann Java Basics - Anfänger-Themen 2
L Frage zur Ticket Maschine Java Basics - Anfänger-Themen 1
J Frage zu OOP-Klassendiagramm Java Basics - Anfänger-Themen 8
OSchriever Frage zu Compiler Java Basics - Anfänger-Themen 8
H Frage zu Throw Exception Java Basics - Anfänger-Themen 2
TimoN11 Frage zu Java-Vererbung (Cast) Java Basics - Anfänger-Themen 5
Bademeister007 Hallo Leute ich hab eine Frage zur ArrayList Java Basics - Anfänger-Themen 8
F Frage betreff Programmierbücher zu Lagerverwaltung als Konsolenprogramm Java Basics - Anfänger-Themen 3
dieter000 Kurze Frage kann mir ejmand kurz diesen Code erklären, bzw wie man die zeilen erklärt und so Java Basics - Anfänger-Themen 1
I String.split regex Frage Java Basics - Anfänger-Themen 2
N Best Practice Frage zum MVC-Pattern Java Basics - Anfänger-Themen 2
dieter000 Frage zu einem Beispiel... Java Basics - Anfänger-Themen 5
J Frage zum Loggen Java Basics - Anfänger-Themen 18
J Methoden Frage: Array-Werte in anderer Methode ändern Java Basics - Anfänger-Themen 4
Zrebna Frage zum "Referenzen-konzept" in Java Java Basics - Anfänger-Themen 8
JD_1998 Array-Position aus einer Methode in einer anderen ausgeben (Kurze Frage) Java Basics - Anfänger-Themen 2
marcooooo Frage zu bestimmten Beispiel Java Basics - Anfänger-Themen 31
NeoLexx equals()-Methode Verständnis Frage anhand Code Beispiel Java Basics - Anfänger-Themen 22
N Input/Output Eine Frage über system.out.println. Java Basics - Anfänger-Themen 10
B Erste Schritte Learning Coding (!) Frage an erfahrene Programmierer. Java Basics - Anfänger-Themen 23
M konzeptuelle Frage: In welcher Klasse definiert man am Besten Methoden, die die Kommunikation mit dem User regeln? Java Basics - Anfänger-Themen 8
B Frage zum Code verständnis im Resultat Java Basics - Anfänger-Themen 10
C Exception-Frage Java Basics - Anfänger-Themen 3
J Eine Frage zur Schreibweise == ? : Java Basics - Anfänger-Themen 3
S Frage des Designs Java Basics - Anfänger-Themen 1
JavaTalksToMe Extends/Implements Frage Java Basics - Anfänger-Themen 3
pkm Frage zu Servletfunktion Java Basics - Anfänger-Themen 0
B Frage zur Währungsumrechnung Java Basics - Anfänger-Themen 3
S Allgemeine Frage über Generics und Vererbungen Java Basics - Anfänger-Themen 5
Kirby.exe Frage zur Verwendung von Interfaces Java Basics - Anfänger-Themen 6
D Frage zu Strings einer Exception Java Basics - Anfänger-Themen 4
L Wie frage ich ab, ob in einem Array, Werte doppelt vorkommen? Java Basics - Anfänger-Themen 4
D Frage zur IDE IntelliJ IDEA Java Basics - Anfänger-Themen 6
H Frage zum 2d Array Java Basics - Anfänger-Themen 1
N Frage zum Newton-Fraktal Java Basics - Anfänger-Themen 1
H Frage zu interfaces Java Basics - Anfänger-Themen 1
J Frage dazu Variablen klassenübergreifend zu verändern Java Basics - Anfänger-Themen 22
I Frage zu SkipList Java Basics - Anfänger-Themen 4
G Frage zu JScrollPane Java Basics - Anfänger-Themen 12
Kirby.exe Allgemeine Frage Java Basics - Anfänger-Themen 3
W Frage zu anonymen Klassen Java Basics - Anfänger-Themen 4
J Kleine Frage zu OOP Java Basics - Anfänger-Themen 371
S Frage Klasse und Objekte Java Basics - Anfänger-Themen 2
F Frage zu Iteratoren Java Basics - Anfänger-Themen 2
C Erste Schritte Frage zur ArrayList Java Basics - Anfänger-Themen 15
J Frage zur Vererbung Java Basics - Anfänger-Themen 1
H Frage zur ermittlung eines doppelte Paars aus Sotieralgorithmus Java Basics - Anfänger-Themen 4
H Frage zum Array Java Basics - Anfänger-Themen 17
G Schach -Frage 2- Maussteuerung Java Basics - Anfänger-Themen 7
G Schach in Java - Allgemeine Frage zur Architektur Java Basics - Anfänger-Themen 7
B Fachliche Frage bei Rechnungen Java Basics - Anfänger-Themen 16
B Frage zu: String... strings -> Ungleiche Anzahl an Parameter? Java Basics - Anfänger-Themen 4
B Frage zu Datenbank Design - Rechnungen, Angebote... und deren Positionen Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben