Klassen als Datentyp nutzen?

iRecordS

Mitglied
Hallo liebe Community,

ich bin gerade dabei die Grundlagen von Java zu lernen. Dabei bin ich auf etwas gestoßen, was ich mir nicht vorstellen kann. Und zwar geht es dabei darum, dass ich einmal die Klasse Tier habe und einmal die Klasse Hund.

Code:
public class Tier {
    private String name;
    private int Alter;
    private String Farbe;
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    .
    .
    .
}

Code:
public class Hund extends Tier {
    private int hundeMarke;
    
    public void getHundeMarke() {
        return hundeMarke;
    }
    
    public int setHundeMarke(int hundeMarke) {
        this.hundeMarke = hundeMarke;
    }
}

Wenn ich jetzt in der Main Klasse ein Objekt von Hund erzeuge, würde ich das so angehen:
Hund meinHund = new Hund();

Allerdings habe ich auch gesehen, dass so etwas möglich ist:
Tier meinHund = new Hund();

Wie soll ich mir das jetzt vorstellen? Welchen Unterschied macht es und in welchen Fällen brauche ich das?

Mfg
iRecordS
 

LimDul

Top Contributor
Das ist einer der Grundpfeiler der Vererbung und Co.
Lektüre: http://openbook.rheinwerk-verlag.de...05_008.htm#mjf275cae4069cb07f60b602bcbea532c8

Angenommen, du hast irgendwo folgende Methode

Java:
public void gibNamenAus(Tier tier) {
  System.out.println(tier.getName());
}

Diese Methode soll natürlich auch funktionieren, wenn du einen Hund reinsteckst.

Jedes Objekt vom Typ Hund ist ja auch gleichzeitig ein Objekt vom Typ Tier. Den Hund ist eine Spezialisierung von Tier.

Wenn du also Tier meinHund = new Hund(); machst, dann erzeugt du zwar ein Objekt vom Typ Hund, weißt es aber einer Variablen von Typ tier zu. Das heißt der Compiler kann nun nur auf die Methoden von der Klasse Tier zugreifen - da der Compiler nicht erkennen kann, was wirklich drin steckt. Das wird erst zur Laufzeit ausgewertet.

z.B. wird dies gerne bei Listen verwendet:

Java:
List<String> meineListe = new ArrayList<>();

Für die weitere Nutzung ist es nicht relevant das es eine ArrayList ist. Wenn du also später dich z.B. mal entscheidest anstelle der ArrayList eine LinkedList zu verwenden, dann musst du nur diese Zeile ändern. Würdest du stattdessen schreiben

Java:
ArrayList<String> meineListe = new ArrayList<>();
und willst es dann austauschen, dann kann es sein dass irgendwo zig Zeilen später jemand eine Methode genutzt hat, die es nur in der ArrayList gibt - und dann kannst die Implementierung nicht mehr austauschen.
 

iRecordS

Mitglied
@LimDul
Wenn du also Tier meinHund = new Hund(); machst, dann erzeugt du zwar ein Objekt vom Typ Hund, weißt es aber einer Variablen von Typ tier zu. Das heißt der Compiler kann nun nur auf die Methoden von der Klasse Tier zugreifen - da der Compiler nicht erkennen kann, was wirklich drin steckt. Das wird erst zur Laufzeit ausgewertet.

Das verstehe ich jetzt aber nicht ganz. Wie ist das gemeint, das der Compiler das nicht erkennt? Kann ich denn jetzt immernoch auf die Methoden von der Klasse Hund und der Klasse Tier zugreifen? Und warum sollte ich dann nicht immer einfach die Superklasse nehmen, wenn ich ein Objekt einer Kindsklasse erzeuge?
 
K

kneitzel

Gast
Wenn Du eine Variable vom Typ Tier hast, dann kann kannst Du da alles rein stecken, das "ein Tier ist" (Das ist etwas blöd formuliert. Das sich wie ein Tier verhält ist besser, aber irgendwie hat sich die andere Ausdrucksweise durchgesetzt), also Hund, Katze, ....

Aber du kannst nur auf das Verhalten von Tier zugreifen. Also kein Bellen oder Miauen ... Denn aus Sicht des Compilers könnte da ja eine Katze drin sein, dann wäre kein Bellen möglich. Oder es könnte ein Hund sein, dann wäre das Miauen nicht möglich.
Der Compiler kann nur auf das Verhalten zurück greifen, das ein Tier bietet. Also z.B. "getName" aufrufen.

Wenn Du ein weitergehendes Verhalten willst, dann musst Du erst prüfen, ob der Typ stimmig ist:
Ist es ein Hund? -> Auf das Verhalten des Hundes zugreifen.
Ist es eine Katze? -> Auf das Verhalten der Katze zugreifen.

Dann gibt es aber auch Interfaces. So ist ein Interface denkbar für Tiere, die Ihre Temperatur regeln. Hunde und Katzen haben das (alle Säugetiere). Eine Schlange reguliert die eigene Temperatur aber nicht, da braucht man das nicht.

Ein Tierarzt kann also auch fragen:
-> Hat es das Verhalten "TemperaturReglung"? -> getTemperatur, getMinNormalTemperature, getMaxNormalTemperature -->Damit können wir die Temperatur kontrollieren.

Und daher nimmst Du immer den Typ, den du brauchst.
Wenn Du ein Gerät entwickelst, das die Temperatur auswertet, dann nimmt das kein Tier, Hund oder Katze entgegen, sondern einfach nur ein "TemperaturReglung". Denn das kann die Temperatur prüfen, sobald dieses Interface implementiert wurde. Es muss die Klassen gar nicht kennen, die das implementieren.
Das Gerät funktioniert also ganz Universell! Du kannst mit dem Gerät auch prüfen, ob die Temperatur von einer CPU ok ist oder ob ein Backofen die richtige Temperatur hat. Es ist unabhängig von dem Tier. ==> Wiederverwendung von Klassen!

Du musst Dir also überlegen, was Du brauchst. Wenn Du ein Lager für Tiere bist, dann nimmst Du ein Tier entgegen. Bist du eine Hundepension, dann nimmst Du nur Hund entgegen.... Willst Du einen Schäferhund haben, dann nimmst Du nur einen Schäferhund entgegen. (Wärst ja auch schön blöd, wenn Du sagst: Ich will ein Schäferhund und dann gibt man dir einen kleinen Dackel..... Das geht einfach nicht.
 

iRecordS

Mitglied
@JustNobody Das Thema mit Interfaces habe ich auch noch nicht ganz verstanden.. wieso sollte ich Klassen haben, welche Variablen und Methoden/Funktionen deklarieren aber nicht initialisieren? In welchen Momenten brauch ich das?

Wenn Du ein weitergehendes Verhalten willst, dann musst Du erst prüfen, ob der Typ stimmig ist:
Ist es ein Hund? -> Auf das Verhalten des Hundes zugreifen.
Ist es eine Katze? -> Auf das Verhalten der Katze zugreifen.

Wie überprüfe ich das denn in dem Falle von Tier neuesTier = new Hund(); ? Kann ich einfach eine Abfrage machen mit:
neuesTier == Hund();? Das sieht jetzt schon falsch aus. ^^
 

White_Fox

Top Contributor
@JustNobody Das Thema mit Interfaces habe ich auch noch nicht ganz verstanden.. wieso sollte ich Klassen haben, welche Variablen und Methoden/Funktionen deklarieren aber nicht initialisieren? In welchen Momenten brauch ich das?
Das brauchst du dann, wenn du erzwingen willst daß ein Objekt ein bestimtmes Verhalten anbietet, aber man nicht wissen kann/will, wie es implementiert wird.

Erstmal ist es wichtig, scharf zu trennen: Ein Interface ist keine Klasse. Sondern es stellt eine Schnittstelle dar, daher in der Regel die Terminologie mit xable. (Serializable, Comparable, ...)

Grob gesagt: Eine Klasse legt fest, was ein Objekt ist. Ist es ein Tier, ein Landfahrzeug, ein Küchengerät, usw. Ein Interface erweitert eine Klasse um eine Fähigkeit, dadurch kann ein beliebiges Objekt schwimmfähig, flugfähig, ... werden.

Beispiel: Du kannst von deiner Klasse "Tier" die Klasse "Säuger" ableiten. Säuger sind z.B. auch Fledermäuse, Flughunde. Diesen beiden Klassen kannst du z.B. ein Interface Flyable mitgeben und dadurch erzwingen, daß diese eine Methode fly(); haben.
Genauso kannst du von "Tier" auch noch "Fisch" ableiten und eine Klasse "FliegenderFisch". Auch dieser Klasse kannst du das Interface "Flyable" mitgeben, aber die Methode muß offensichtlich ganz anders implementiert werden, da ein FliegenderFisch längst nicht so weit fliegt wie eine Fledermaus.
Auf jeden Fall kannst du damit alle Flugfähigen Tiere gleich behandeln, wenn du ein Flyable flieger = new Fledermaus(); instanzierst.


Wie überprüfe ich das denn in dem Falle von Tier neuesTier = new Hund(); ? Kann ich einfach eine Abfrage machen mit:
neuesTier == Hund();? Das sieht jetzt schon falsch aus. ^^

Schau dir mal den instanceOf-Operator an.
 

White_Fox

Top Contributor
Um mal auf die Frage im Threadtitel zurückzukommen:

Klassen sind NICHT das Äquivalent zu Strukturen in C. Klassen sind keine Datentypen.
Ich muß allerdings zugeben, mehr habe ich in Klassen eigentlich auch nicht gesehen bevor ich mich ernsthaft mit Objektorientierung beschäftigt habe. Ich würde dir raten, mal ein gutes Buch zu Entwurfsmustern zu lesen, das wird dir auf vieles einen ganz neuen Blick geben.

 

iRecordS

Mitglied
@White_Fox
Um mal auf die Frage im Threadtitel zurückzukommen:

Klassen sind NICHT das Äquivalent zu Strukturen in C. Klassen sind keine Datentypen.
Mit C kenne ich mich leider gar nicht aus. Allerdings, was ist die Klasse denn sonst in diesem Falle: Tier hund;

Auf jeden Fall kannst du damit alle Flugfähigen Tiere gleich behandeln, wenn du ein Flyable flieger = new Fledermaus(); instanzierst.

Ich kann Interfaces ebenfalls als "Datentyp" nutzen? Und außerdem, wenn ich mir deine Erklärung so durchlese, dann wirkt es für mich sinnvoll, für jede Kindsklasse ein neues Interface (bzw. ein Interface für mehrere Kindsklassen wo es zutrifft, wie hier mit flyable) zu erstellen und die jeweiligen abweichenden Funktionen zu erstellen, welche die Vaterklasse nicht anbietet.
 

White_Fox

Top Contributor
Allerdings, was ist die Klasse denn sonst in diesem Falle: Tier hund;

Eine Struktur in C ist im Prinzip ein Bündel aus anderen Datentypen. Du kannst z.B. eine Struktur "Rectangle" erstellen, die zwei Doubles enthält und nennst diese a und b.

Das kannst du mit einer Klasse auch machen. Aber, und das ist der Unterschied: Du kannst einer Klasse auch ein Verhalten beibringen. Beispiel:
Java:
public abstract class Tier{
    public abstract void gibLaut();
}

public class Katze extends Tier{
    @Override
    public void gibLaut(){
        System.out.println("Miau Miau");
    }
}

public class Hund extends Tier{
    @Override
    public void gibLaut(){
        System.out.println("Wuff Wuff");
    }
}

Hier passiert folgendes: In der Klasse Tier wird festgelegt, daß es eine Methode gibLaut() geben muß. Die Methode ist abstrakt, d.h. es ist festgelegt daß sie da sein muß, Rückgabetyp, welche Parameter erwartet werden, usw. Damit muß jede Klasse, die von Tier abgeleitet wird, diese Methode implementieren. Das machen die Klassen Hund und Katze, aber wie du siehst muß jede Methode anders implementiert werden, damit es für die jeweilige Klasse paßt.



Ich kann Interfaces ebenfalls als "Datentyp" nutzen? Und außerdem, wenn ich mir deine Erklärung so durchlese, dann wirkt es für mich sinnvoll, für jede Kindsklasse ein neues Interface (bzw. ein Interface für mehrere Kindsklassen wo es zutrifft, wie hier mit flyable) zu erstellen und die jeweiligen abweichenden Funktionen zu erstellen, welche die Vaterklasse nicht anbietet.
NEIN! Ein Datentyp ist etwas um bestimmte Daten zu speichern, das macht ein Interface nicht. Ich meinte mit "gleich behandeln" so etwas:
Java:
public void someMethode(Flyable flyable){
    flyable.fly();  //Völlig egal ob das Flyable eine Fledermaus oder sonstwas ist.
}
 

White_Fox

Top Contributor
Du kannst eine Klasse natürlich als selbstdefinierten Datentypen verwenden. Aber du kannst einem Datentypen kein weiteres Verhalten beibringen, insofern würde ich bei meiner Aussage bleiben.

Aber das ist Definitionssache, davon hab ich wiederum kaum Ahnung, ich nehme daher einfach mal an daß du Recht haben könntest. :)
 

mrBrown

Super-Moderator
Mitarbeiter
Erstmal ist es wichtig, scharf zu trennen: Ein Interface ist keine Klasse. Sondern es stellt eine Schnittstelle dar, daher in der Regel die Terminologie mit xable. (Serializable, Comparable, ...)

Grob gesagt: Eine Klasse legt fest, was ein Objekt ist. Ist es ein Tier, ein Landfahrzeug, ein Küchengerät, usw. Ein Interface erweitert eine Klasse um eine Fähigkeit, dadurch kann ein beliebiges Objekt schwimmfähig, flugfähig, ... werden.
Da würde ich zumindest in Teilen widersprechen.

Ein Interface legt genauso wie eine Klasse fest, was ein Objekt ist, in deinem Beispiel könnte Tier und Landfahrzeug auch ein Interface sein (wie zB List im JDK). Die Interfaces stellen nicht eine "Fähigkeit" zur Verfügung, sondern stellen einen ganzen Typen da, Benennung wie bei Klassen daher üblicherweise ein Nomen, die meisten Interfaces dürften dieser Art sein. Für den Nutzer des Types sollte es dabei vollkommen egal sein, ob er Interface oder Klasse nutzt.

Auf *able endende Interfaces stellen entweder, wie du auch beschrieben hast, Typen-übergreifende "Fähigkeiten" dar, oder dienen als Marker-Interface.
Für ersteres ist Comparable ein gutes Beispiel, oder aush Iterable, was zB von List erweitert wird.
Zweitens ist zB Serializeable oder Cloneable - das Interface stellt selber keinerlei Methoden zur Verfügung, sondern dient nur als "Markierung", dass der implementierende Typ irgendeine Besonderheit aufweist, die allerdings keine Methoden sind.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Methodenaufrufe abstrakte Klassen, Interfaces Java Basics - Anfänger-Themen 17
M Abstrakte Klassen - Notation Java Basics - Anfänger-Themen 9
Detlef Bosau Nachladen von Klassen zur Laufzeit Java Basics - Anfänger-Themen 24
M Anonyme Klassen - Warum wird in der Konsole nichts ausgegeben? Java Basics - Anfänger-Themen 1
MoxMorris Einige Methoden aus verschiedenen Klassen nacheinander auszuführen läuft seltsam Java Basics - Anfänger-Themen 2
I Klassen von einem package laden, Statisches Feld auslesen und Objekt erstellen Java Basics - Anfänger-Themen 8
I 2 verschiedene Klassen mit gleichen Property vergleichen Java Basics - Anfänger-Themen 13
C Array von Klassen Java Basics - Anfänger-Themen 2
monsterherz 2 Klassen daher Probs mit dem Dateinamen Java Basics - Anfänger-Themen 9
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 9
I JPA Query für mehrere Klassen Java Basics - Anfänger-Themen 3
I @Entity Klassen, Service Beans etc. aus einem Share Projekt beziehen? Java Basics - Anfänger-Themen 26
S IntelliJ geht alle Klassen durch Java Basics - Anfänger-Themen 9
I Gleiche Klassen und Methoden in unterschiedlichen Projekten nutzen Java Basics - Anfänger-Themen 2
T variablen klassen übergreifend Java Basics - Anfänger-Themen 12
N Klassen Methoden anderer Klassen aufrufen Java Basics - Anfänger-Themen 4
D Klassen Klassen Kommunikation Java Basics - Anfänger-Themen 12
Encera Auf Objekte aus anderer Klassen zugreifen Java Basics - Anfänger-Themen 20
berserkerdq2 Zwei Klassen Erben von der Klasse A, die eine Klasse kann ich an Methoden übergeben, die als Parameter A haben, die andere nicht? Java Basics - Anfänger-Themen 3
M Andere Methoden in anderen Klassen aufrufen Java Basics - Anfänger-Themen 11
L Methoden in anderen Klassen nutzen Java Basics - Anfänger-Themen 6
D Klassen und Vererbung Java Basics - Anfänger-Themen 2
L Best Practice Annotierte Klassen im Classpath herausfinden Java Basics - Anfänger-Themen 1
P Mit dem Scanner Klassen aufrufen Java Basics - Anfänger-Themen 3
O Klassen Zusammenspiel zwischen 2 Klassen Java Basics - Anfänger-Themen 1
K Zweite Ausgabe von vererbten Klassen Java Basics - Anfänger-Themen 3
M Wie können Klassen nicht-materialisierte Attribute haben, die nur über get/ set-Mehoden simuliert sind? Java Basics - Anfänger-Themen 6
Speedrunner klassen aufrufen Java Basics - Anfänger-Themen 41
M Log4J (v2) nachträglich in allen Klassen hinzufügen Java Basics - Anfänger-Themen 9
D importieren eigener Klassen Java Basics - Anfänger-Themen 12
W Wo ist der Wurm in meinem Grundverständnis von Klassen? Java Basics - Anfänger-Themen 22
S Daten/Klassen/Packages richtig updaten!? Java Basics - Anfänger-Themen 2
alice98 Erste Schritte Liste erstellen ohne vorgefertigte Klassen Java Basics - Anfänger-Themen 1
C Archiv für eigene Klassen Java Basics - Anfänger-Themen 9
S Objekte von zwei klassen in zwei verschiedene Textdateien schreiben Java Basics - Anfänger-Themen 5
elsaaaaaa Wochentag als String ausgeben mit JDK Klassen Java Basics - Anfänger-Themen 6
CptK Generics: Klassen die Interface implementieren, aber selbst nicht das Interface sind Java Basics - Anfänger-Themen 8
Z Mehtode bei Start des Programms ausführen (Klassen übergreifend) Java Basics - Anfänger-Themen 12
J Allgemeines Problem mit Klassen Java Basics - Anfänger-Themen 5
TimoN11 Java Klassen Global einbinden Java Basics - Anfänger-Themen 1
B Inventar als einzelne Klassen anlegen? Java Basics - Anfänger-Themen 12
G Java Klassen und Instanzmethoden Java Basics - Anfänger-Themen 15
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 3
T Vererbung Verschiedene Attribute für vererbte Klassen Java Basics - Anfänger-Themen 4
S Klassen instanziieren und verwenden von Getter und Setter Java Basics - Anfänger-Themen 4
B Variablen Variablen übertragen ohne Klassen Java Basics - Anfänger-Themen 5
C Fernseher-Aufgabe (Methoden, Klassen und Objekte) Java Basics - Anfänger-Themen 63
H Methoden in großen Klassen gruppieren oder auslagern? Java Basics - Anfänger-Themen 10
G Abstrakte Klassen Java Basics - Anfänger-Themen 11
Y Klassen Klassen und Objekte Java Basics - Anfänger-Themen 3
Y Klassen Klassen und Objekte mit set und get Java Basics - Anfänger-Themen 0
A Generischen Klassen Java Basics - Anfänger-Themen 8
A Vererbung Klassen im Bezug auf Auto´s Java Basics - Anfänger-Themen 18
A Generische Klassen/Interface Java Basics - Anfänger-Themen 1
A Klassen Vererbung und zusätzliche Unterklassen Java Basics - Anfänger-Themen 23
J 2 klassen benutzen Java Basics - Anfänger-Themen 5
A Klassen und methoden Java Basics - Anfänger-Themen 15
A Bankweverwaltung mit Klassen und Methoden Java Basics - Anfänger-Themen 14
J Klassen Problem Java Basics - Anfänger-Themen 8
I Java Klassen "Graphics" und "MouseEvent" kombinieren Java Basics - Anfänger-Themen 7
M Aufsplitten von Methoden in andere Klassen Java Basics - Anfänger-Themen 2
M (Sehr großes Problem) Listen als static in anderen Klassen verwendet Java Basics - Anfänger-Themen 12
C Klassen objektorientiert aufteilen Java Basics - Anfänger-Themen 6
hello_autumn Klassen Anzahl sowie die Anzahl der Junit Tests ermitteln? Java Basics - Anfänger-Themen 8
A Auf Eigenschaften von Objekten anderer Klassen zugreifen Java Basics - Anfänger-Themen 5
F Klassen und Pakete Projektübergreifend (Eclipse) Java Basics - Anfänger-Themen 6
V_Fynn03 Klassen Überweisungen tätigen und einzahlen mit 2 Klassen Java Basics - Anfänger-Themen 1
W Abarbeitungsreihenfolge Anonyme Klassen Java Basics - Anfänger-Themen 2
V_Fynn03 Bruchrechner programmieren (2 Klassen) Java Basics - Anfänger-Themen 9
D OOP- Eine Klasse in mehrere Klassen aufteilen Java Basics - Anfänger-Themen 7
J Problem mit Array: 2 Klassen Java Basics - Anfänger-Themen 2
W Frage zu anonymen Klassen Java Basics - Anfänger-Themen 4
Curtis_MC Parameter-Übergabe bei Klassen und Methoden Java Basics - Anfänger-Themen 12
E Klassen implementieren Java Basics - Anfänger-Themen 94
T Interfaces in erbenden Klassen Java Basics - Anfänger-Themen 2
C Methoden/Klassen Übergabewerte Java Basics - Anfänger-Themen 8
C Java Klassen/Methoden/Übergabeparameter Java Basics - Anfänger-Themen 4
L Wie geht man bei mehreren Action Klassen vor? Java Basics - Anfänger-Themen 0
P Datentypen, Klassen, Operatoren, Wrapperklassen Java Basics - Anfänger-Themen 2
L Wie teilt man ein Programm in vernünftige Klassen ein? Java Basics - Anfänger-Themen 10
T Klassen Denkfehler im Klassen "dynamisch" instanzieren? Java Basics - Anfänger-Themen 4
P Zugriff auf Variablen anderer Klassen in Greenfoot Java Basics - Anfänger-Themen 1
A Methode, Klassen Java Basics - Anfänger-Themen 3
B UML Klassen Diagramm zu Java Code Programmieren und ausführen Java Basics - Anfänger-Themen 21
J Zwei Klassen die sich gegenseitig referenzieren - Bad practice? Java Basics - Anfänger-Themen 4
G Klassen und Objekte Java Basics - Anfänger-Themen 2
Java The Hutt SetWerte über verschiedene Klassen Java Basics - Anfänger-Themen 16
D Klassen ausgeben Java Basics - Anfänger-Themen 2
H linkedlist generische klassen Java Basics - Anfänger-Themen 169
B CSS Klassen in eine Liste schreiben Java Basics - Anfänger-Themen 4
Queiser Nicht statische Klassen Java Basics - Anfänger-Themen 6
neerual Klassen Wie rufe ich Klassen, die andere Klassen extenden in einer Test Unit auf? Java Basics - Anfänger-Themen 10
J Gleiche Methode in 2 verschiedenen Klassen - Lösung ? Java Basics - Anfänger-Themen 8
G Refactoring von mehreren identischen Klassen Java Basics - Anfänger-Themen 36
O Wrapper Klassen Java Basics - Anfänger-Themen 6
CptK Best Practice Klassendiagramm aus fertigen Klassen erstellen lassen Java Basics - Anfänger-Themen 2
R OOP Instanzierung in verschiedenen Klassen Java Basics - Anfänger-Themen 8
N Project layout eclipse ( seperate ordner für klassen ? ) Java Basics - Anfänger-Themen 1
B Vererbung Abgeleitete Klassen Bestimmter Typ zuweisen Java Basics - Anfänger-Themen 2
E Best Practice Jar-file mit zwei Klassen und externer Bibliothek über Konsole erzeugen Java Basics - Anfänger-Themen 13

Ähnliche Java Themen

Neue Themen


Oben