Datentyp von einer Klasse

oraclin25

Erfahrenes Mitglied
Hallo zusammen,

ich habe folgende Codezeile:

Code:
Source xsltSource = new StreamSource(Datei);

StreamSource ist eine Klasse. Ich wollte wissen, woher es dokumentiert ist, dass von StreamSource der Datentyp Source ist. Gegooget, in die Doku nachgeschlagen, habe ich dann folgende Erkenntnis gewonnen:

Code:
java.lang.Object
    ----->  javax.xml.transform.stream.StreamSource
All Implemented Interfaces: 
Source

public class StreamSource
extends Object
implements Source

Könnte mir jemand bitte helfen, wieso StreamSource den Datentyp Source hat? Vielen Dank.

Schöne Grüße aus Rheinland,

Eure Ratna
 
Hi

steht doch da: Das Interface Source wird implementiert.

Ein Interface hat ja eine Liste von Methoden mit Parametern etc.
und schreibt jeder Klasse, die das Interface implementieren will, vor,
dass die Klasse mindestens diese Methoden fertig programmiert und aufrufbar haben muss.

Die Klassen die Source implementieren unterscheiden sich zwar alle, haben aber wie gesagt alle mindestens die Methden xyz mit den Parametern abc, wie sie in Source festgelegt werden.
Was diese Methoden bei welcher Klasse machen ist so nicht gesagt,
aber man kann sie zumindest aufrufen.

Wenn man StreamSource jetzt mit einem "implements Source" kompiliert
prüft der Compiler das auch, ob die geforderten Methoden alle da sind.


Wenn du jetzt eine Variable vom Grundtyp Source hast kannst du mit der alles machen,
was das Interface Source eben anbietet.
Sachen, die das StreamSource drin hat, aber nicht von Source gefordert sind,
gehen nicht direkt zum Aufrufe (obwohl man ja weiß, dass ein StreamSource drin ist).

Damit ist sichergestellt, dass du der Source-Variable alles zuweisen kannst,
was die Source-Methoden auch hat (und das mit dem implement "beweist")
 
Hallo sheel,

vielen Dank erstmal für die rasche Antwort.

Aber die Klasse StreamSource muss doch nicht unbedingt als Ausgabe etwas vom Typ Source haben, oder? Bsp:

(völlig willkürliche Methoden und ihre Implementierung)

public interface Source{
public String getSystemId();
}

public class StreamSource extends Object implements Source(
void methode1(){...}
getSystemId(){...}
)

Also, warum ist das nicht eher so:
Code:
StreamSource xsltSource = new StreamSource(Datei);

Stattdessen ist es so:
Code:
Source xsltSource = new StreamSource(Datei);

Weil, interface dient ja eigentlich lediglich als zusätzliche Erweiterunen von Methoden bzw. Variablen.

Danke schön.

Schöne Grüße aus Rheinland,

Eure Ratna
 
Hallo sheel,

Weil, interface dient ja eigentlich lediglich als zusätzliche Erweiterunen von Methoden bzw. Variablen.

Das ist nicht der Sinn eines Interfaces; denn zusätzliche Methoden können einfach in die Klasse eingefügt werden. Wozu in diesem Fall das Interface?
Der Sinn von Interfaces ist, eine Art Vertrag vorzugeben, diesen Vertrag müssen die Klassen einhalten welche das Interface implementieren.

In deinem Beispiel kann ich mich darauf verlassen, dass ein Objekt vom Typ Source die Methode getSystemId() hat. Es spielt dabei keine Rolle welche weiteren Methoden das Objekt noch hat oder welchen konkreten Typ es hat.
Stell dir oben vor du hättest noch eine weitere Klasse vom Typ HTTPStreamSource(URL). Dein Programm speichert jetzt z.B. folgende Variable:
Code:
private Source source;

public setSource(Source source) { this.source = source; }

...
public void method1() {
   // mach was
   meinService.machWasMit(source.getSystemId());

}

Jetzt ist es für deine Klasse hier völlig egal von welchem Typ dein Source ist, Hauptsache es implementiert das Interface.
Du kannst jetzt z.B. auch zur Laufzeit deine Implementierung austauschen indem du z.B. ein HTTPStreamSource Objekt welche auch das Interface implementiert mittles
setSource(myHttpStreamSource)
setzt.
Und nun hast du die "Art" geändert wie das Objekt source arbeitet.
 
Hallo socke77,

vielen Dank für die Hilfestellung. Ehrlicherweise bin ich jetzt ein bisschen stutzig, da ich nicht mehr weiß ob meine Verständnisvorstellung überhaupt noch stimmt:

1. Angenommen, folgende Zeile:
Code:
Tier h = new Hund();

Ich habe so verstanden, dass obiges von rechts nach links zu interpretieren gilt. Es wird erstmal ein Objekt erstellt, ein Hund-Objekt, dann wird dieses Objekt referenziert von der Bezeichnung h, wobei h den Datentyp Tier hat.

2. Wieso ist dies möglich? Durch Hund implements Tier, besitzt ein Hund-Objekt alle Methodendeklarationen bzw. Variablen(richtig?) aus Tier; insbesonderen sind die Deklarationen in der Hund-Klasse unbedingt zu definieren.

3. h zeigt somit auf das Hund-Objekt.

4. Ich glaube, mein Denkfehler war folgendes:
Tier h stellte ich mir bildlich sehr "mager" vor(weil h vom ersten Blick lediglich Tier ist). Dabei ist h eine Referenz auf Hund + Tier. h ist nicht "mager", sondern "fett" :rolleyes:

5. Nun, ich nehme einfach mal an, andersrum wäre auch kein Problem:
Hund h = new Hund();
Nur, es gibt Konstellationen (Erkenntnis aus Links von TheBear), wo Tier h = new Hund();
effizienter ist.

Wie findest Du diesen Blickwinkel zum Verständnis?

Schöne Grüße aus Rheinland,

Eure Ratna
 
zu 1.) Wenn deine Klasse Hund von der Klasse Tier erbt (oder das interface Tier implementiert) stimmt diese Zuweisung.
zu 2.) Durch
Code:
Hund implements Tier
besitzt Hund alle Methoden aus Tier, ja. Genauso muss Hund all diese Methoden überschreiben.
zu 3.) Stimmt
zu 4.) h ist eine Variable, die auf ein Objekt des Datentyps Tier (oder irgendeines seiner Subtypen [Datentypen/Klassen, die von Tier erben oder Tier implementieren]) zeigt.
zu 5.)
Code:
Hund h = new Hund();
stimmt auch. Effizienter ist
Code:
Tier h = new Hund();
nicht unbedingt. Es kommt da stark auf deine Anwendungsweise an. Wenn du Tier h = new Hund() macht, dann kannst du in der Variable h nur auf die Methoden der Schnittstelle Tier zugreifen, da das Programm nicht weis, das da ein Hund drin gespeichert ist. Dafür kannst du nachher im Code z.B.:
Code:
h = new Katze();
schreiben, und es gibt kein Fehler, solange Katze auch die Schnittstelle Tier implementiert.
 
Hallo socke77 und doe300,

vielen lieben Dank für die Hilfestellungen. Eine Sache habe ich noch nicht so richtig verstanden:
Code:
private Source source;

public setSource(Source source) { this.source = source; }

...
public void method1() {
   // mach was
   meinService.machWasMit(source.getSystemId());

}

Obiges ist eine Klasse, die so deklariert ist:
Code:
public class HTTPStreamSource( ) implements Source

Wenn ich zum Beispiel ein Objekt von der Klasse HTTPStreamSource erzeuge:
Source meinObjekt = new HTTPStreamSource( );
, dann habe ich ja zunächst einmal lediglich einen "Zeiger" namens source, ich bestimme noch nicht, auf welches Objekt dieser "Zeiger" referenziert. Soweit so gut.

Kann ich folgende Methode ausführen?

meinObjekt.setSource(meinObjekt);

Also, als Parameter wird hier das aufrufende Objekt weitergegeben. Geht das?

Vielen Dank.

Schöne Grüße aus Rheinland,

Eure Ratna:p
 
Mit
Code:
Source meinObjekt = new HTTPStreamSource();
erstellst du einen Zeiger (Teil links des Zuweisungsoperators "=") UND bestimmst auf welches Objekt er deutet (rechts vom "="), nämlich auf das gerade neu erstellte Objekt vom Typ HTTPSourceStream.
Also kannst du ab dieser Codezeile mit dem Objekt arbeiten, d.h. dein Aufruf
Code:
meinObjekt.setSource(meinObjekt);
ist damit gültig.
Soweit ist dann alles richtig.
Eine inhaltliche Frage hätte ich noch, warum du dem Objekt sich selber als Quelle (source) angibst?
 
Hallo doe300,

Eine inhaltliche Frage hätte ich noch, warum du dem Objekt sich selber als Quelle (source) angibst?

wenn ich ehrlich bin, weil ich den Ratschlägen gefolgt bin. Ich sehe persönlich eigentlich auch keinen Vorteil, warum man das so macht, statt der Variable vom Anfang an direkt den "größeren" Datentyp zu geben, also:
Code:
HTTPStreamSource meinObjekt = new HTTPStreamSource();

Es wird oft geschildert, dass beim obigen Code frau viel umzuändern hat, wenn meinObjekt aus anderen Klasse kommt. Also stattdessen soll man folgendes machen:
Code:
Source meinObjekt = new HTTPStreamSource();

Hierbei müsste man einzigst auf folgendes umändern:
Code:
Source meinObjekt = new XMLStreamSource();

Aber ich meine, ich könnte auch ganz einfach von
HTTPStreamSource meinObjekt = new HTTPStreamSource();
auf
XMLStreamSource meinObjekt = new XMLStreamSource();

Könnte jemand vielleicht behilflich sein?

Schöne Grüße aus Rheinland,

Eure Ratna:)
 
Grund dafür, eine abstrakte Klasse oder ein Interface zu verwenden ist, dass man so festgelegte APIs nicht umschreiben muss, wenn sich im Hintergrund irgend etwas verändert.
 
Zurück