gleicher Name in der Basisklasse und in der Subklasse

ernst

Top Contributor
Hallo allerseits,
siehe Quellcode unten
Mit
((Vater)this).name
wird auf das Attribut name des Vaters zugegriffen und nicht auf den des Sohnes!
Warum wird aber mit
((Vater)this).print();
nicht auf die Methode des Vaters zugeriffen, sondern auf die
print() des Sohnes ?

Das ist mir absolut unverständlich.

mfg
Ernst


Code:
public class Startklasse {
    public static void main(String[] args){
            Sohn s = new Sohn("klaus", "walter");
            s.print();
    }
}

class Vater{
    String name;

        public void print(){
            System.out.println("Ich bin der Vater");
        }
      
    public Vater(String name){
            this.name=name;          
    }
}

class Sohn extends Vater{
    String name;
  
        public void print(){
            System.out.println("Vater_name="+((Vater)this).name);
            ((Vater)this).print();
        }
      
    Sohn(String name, String vname){
            super(vname);          
            this.name=name;          
    }
}
 
Zuletzt bearbeitet:

httpdigest

Top Contributor
Weil nur Methodenaufrufe polymorph sind bzw. überschrieben werden können, nicht aber Instanzvariablenzugriffe. Hier "versteckst" du die Variable der Elternklasse nur durch die Redeklaration einer Variablen mit demselben Namen in einer Kindklasse und brauchst den qualifizierten Zugriff auf die Variable durch Cast bzw. Nennung des Typs.
Es ist also egal, zu welchem konkreten Zieltyp du einen Aufruf einer überschriebenen, nicht-statischen Methode castest: Es entscheidet immer nur der Laufzeittyp des Empfängerobjektes, auf dem du die Methode aufrust, welche konkrete überschriebene Methode letztlich aufgerufen wird - nicht der Compilezeittyp des Ausdrucks, auf dem du die Methode aufrust.
 

ernst

Top Contributor
entscheidet immer nur der Laufzeittyp des Empfängerobjektes, auf dem du die Methode aufrust, welche konkrete überschriebene Methode letztlich aufgerufen wird - nicht der Compilezeittyp des Ausdrucks, auf dem du die Methode
Vielen Dank für die Antwort.
Aber woher weiß man, wer der
"Laufzeittyp des Empfängerobjektes, auf dem du die Methode aufrust"
ist?
Kannst du mir das konkret an dem Beispiel zeigen ?

mfg
Ern
 

LimDul

Top Contributor
Das weiß man eben nicht - das wird eben erst zur Laufzeit festgelegt.

3 Klassen
Java:
public class A {
  public doSomething() {}
}

public class B extends A {
  public doSomething() {}
}

public class C extends A {
  public doSomething() {}
}

Wenn ich jetzt folgenden Code habe:


Java:
A meineVariable = holeMirEinObjekt();
meineVariable.doSomething();

Dann hängt es davon, was holeMirEinObjekt zurückgibt - ob es ein A, B oder C Objekt zurückgibt. Das sieht man dem Code aber nicht an.

Evtl. ist das z.B. Abhängig von der Uhrzeit etc. Die Idee von Polymorphismus ist eben, dass man es nicht wissen muss (bzw. gar nicht soll). Beispiel die Klasse List aus Java (bzw. genauer das Interface, aber für die Erklärung ist das gerade egal).

List bietet eine Methode size() an, die die Anzahl der Elemente zurückliefert. Wenn ich die Aufrufe, ist mir als Aufrufer vollkommen egal, welche konkrete Ableitung von List ich in der Hand habe - ob das eine ArrayList ist, eine LinkedList, einen Stack oder sonst was. Java sorgt zur Laufzeit dafür, dass die korrekte Implementierung aufgerufen wird.
 

ernst

Top Contributor
Erstmal vielen Dank für deine Antwort.

Ich beziehe mich im Folgenden auf mein Anfangsbeispiel:
>
>Aber woher weiß man, wer der
>"Laufzeittyp des Empfängerobjektes, auf dem du die Methode aufrust"
>ist?
>

Meine Antwort:
Der Laufzeittyp ist Sohn
Das Empfängerobjekt ist s
Stimmt das ?

Wenn s das Empfängerobjekt ist, dann wird
s.print aufgerufen.
Also wird der folgende Programmcode abgearbeitet:
System.out.println("Vater_name="+((Vater)this).name);
((Vater)this).print();

Mir ist allerdings nicht klar, warum das Empfängerobjekt s
dann nicht
((Vater)this).print();
also (da this hier gleich s ist)
((Vater)s).print();
aufrufen kann.

mfg
Ern
 

httpdigest

Top Contributor
Meine Antwort:
Der Laufzeittyp ist Sohn
Das Empfängerobjekt ist s
Stimmt das ?
Wenn du den Code hier meinst:
Java:
Sohn s = new Sohn("klaus", "walter");
s.print();
Dann ist der Laufzeittyp des Objektes, auf dem print() aufgerufen wird, Sohn. Korrekt.
Objekte allerdings haben keine Bezeichner in Java. Also das Empfängerobjekt ist nicht `s`, sondern:
Das Objekt, auf dem die `print()` Methode aufgerufen wird, befindet sich in der lokalen Variablen `s`.
Das Auswerten dieser Variablen durch den Ausdruck `s` liefert das Objekt (vom Typ `Sohn`) und der Aufruf der Methode per `.print()` ruft dann eben auf diesem Objekt die Methode `print()` auf.

Mir ist allerdings nicht klar, warum das Empfängerobjekt s
dann nicht
((Vater)this).print();
also (da this hier gleich s ist)
((Vater)s).print();
aufrufen kann.
Wieso nicht? Tut es doch. Erstmal ist der Ausdruck ((Vater)this) hier völlig unnötig. Du machst einen Upcast zu einem Typ, den das Objekt sowieso selber schon hat und rufst dann eine überschriebene Methode auf. Und der Aufruf einer überschriebenen Methode ruft _immer_ die am meisten überschriebene Methode ausgehend vom Laufzeittyp des Empfängerobjektes auf.
Vielleicht meinst du eher: `super.print()`?

Oder vielleicht nennst du auch erstmal das eigentliche Problem bzw. die zu lösende Aufgabe?
 
K

kneitzel

Gast
Also Du hast einen Apfel. Und es gibt diverse Behälter:
Einen allgemeinen Behälter,der beliebige Objekte (auch Äpfel) beinhalten kann.
Eine Obsttasche - die nimmt nur Obst. Also auch Äpfel.
Eine Apfelverpackung - da kann man nur Äpfel rein tun.

Wenn Du nun die Methode "essen" vom Apfel aufrufst: Isst du etwas anderes abhängig davon, ob der Apfel nun aus der Apfelverpackung, Obsttasche oder dem allgemeinen Behälter kommt?

Die Aufbewahrung ist jetzt die Variable.
Dieses (Vater) s kannst Du auch ähnlich sehen. Du hast zwar keinen wirklichen "Behälter" aber sieh es einfach einmal als eine Art: Nimm einen "Vater" Behälter und pack es dann da rein und arbeite dann weiter mit diesem Vater Behälter.

Wenn man das auf mein Beispiel überträgt: Das Objekt kommt aus einem allgemeinen Behälter. Da ich aber auf jeden Fall einen Apfel essen will, packe ich es erst ein einen Apfel Behälter. Sollte ich keinen Apfel bekommen haben, dann passt das Teil einfach nicht und Du bekommst eine Exception.

Also generell: Egal was Du mit dem Gegenstand machst: Du machst es immer mit dem Gegenstand. Ein Apfel bleibt ein Apfel, auch wenn es in einen anderen Behälter kommt.
 

Blender3D

Top Contributor
Das ist mir absolut unverständlich.
Das was Du willst ist:
Java:
class Sohn extends Vater {
    String name;

    public void print() {
        System.out.println("Vater_name=" + ((Vater) this).name);
        super.print();
    }

    Sohn(String name, String vname) {
        super(vname);
        this.name = name;
    }
}
Dein Code hat eine endlose Rekursion zur Folge. Weil Du in der Methode print() die Methode noch einmal rekursiv aufrufst. Mit this verweist Du wieder auf das Objekt selbst --> Es wird die Methode von Sohn aufgerufen. Der Cast auf den Type Vater funktioniert, weil Sohn ja von Vater erbt.
Java:
public void print(){ System.out.println("Vater_name="+((Vater)this).name); ((Vater)this).print(); }
;)
 

ernst

Top Contributor
Und der Aufruf einer überschriebenen Methode ruft _immer_ die am meisten überschriebene Methode ausgehend vom Laufzeittyp des Empfängerobjektes auf.
Was ist "die am meisten überschriebene Methode" ?

Mir ist immer noch nicht die Vorgehensweise klar, welches print() ermittelt wird:
Die Variable s hat den Datentyp Sohn und Datentyp Vater.
Problem1:
Welcher Datentyp wird genommen?

Problem2:
Wenn es der in der Hierarchie am weitesten oben stehende Datentyp ist (hier also Vater), dann gibt es wieder (auf die Hierarchie bezogen) 2 Hierarchien, die gleich oder darunter liegend sind, nämlich Vater und Sohn.
Von welcher wird nun das zugehörige print() ausgewählt.

Ich will eben nur den "Algorithmus" dafür wissen, welches print() ausgewählt wird.

mfg
Ern
 

LimDul

Top Contributor
Was ist "die am meisten überschriebene Methode" ?

Mir ist immer noch nicht die Vorgehensweise klar, welches print() ermittelt wird:
Die Variable s hat den Datentyp Sohn und Datentyp Vater.
Problem1:
Welcher Datentyp wird genommen?

Problem2:
Wenn es der in der Hierarchie am weitesten oben stehende Datentyp ist (hier also Vater), dann gibt es wieder (auf die Hierarchie bezogen) 2 Hierarchien, die gleich oder darunter liegend sind, nämlich Vater und Sohn.
Von welcher wird nun das zugehörige print() ausgewählt.

Ich will eben nur den "Algorithmus" dafür wissen, welches print() ausgewählt wird.

mfg
Ern
Du hast die falsche Sichtweise.

Die Variable s hat den Typ Sohn => Das heißt die Aussage ist "Hier ist ein Objekt drin gespeichert, was entweder der Klasse Sohn oder einer Subklasse davon entspricht"

Damit weiß der Compiler "In dem Objekt, was in der Variable s gespeichert wird gibt es die Methode print".

Zur Laufzeit kommt der Laufzeitumgebung und stellt fest: Ah ich soll in dem Objekt, was in s gespeichert wird, die Methode print aufrufen ohne Parameter (Hint: Hier ist im Endeffekt egal welchen Typ die Variable s hat). Ok, dann schauen wir doch mal was für eine Typ das Objekt hat das drin steckt? (wäre, wenn man es programmieren würde s.getClass()). Gibt es da eine Methode print ohne Parameter? Wenn ja => Rufe sie auf. Wenn nein: Dann schau ich mal die Oberklasse an. Gibt es da eine Methode print ohne Parameter? usw. Wenn man am Ende bei Object angekommen ist und es da auch die Methode nicht gibt, wirft die Laufzeitumgebung eine NoSuchMethodException.
 

httpdigest

Top Contributor
Ich will eben nur den "Algorithmus" dafür wissen, welches print() ausgewählt wird.
Der ganz genaue Algorithmus für sogenanntes polymorphes "dynamic dispatch" ist hier beschrieben: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.4.4
Fange an zu lesen ab:
Otherwise, the invocation mode is interface, virtual, or super, and overriding may occur. A dynamic method lookup is used. The dynamic lookup process starts from a class S, determined as follows:
Der Fall "virtual" ist der Fall, der dich interessiert.
 

ernst

Top Contributor
Zur Laufzeit kommt der Laufzeitumgebung und stellt fest: Ah ich soll in dem Objekt, was in s gespeichert wird, die Methode print aufrufen ohne Parameter (Hint: Hier ist im Endeffekt egal welchen Typ die Variable s hat). Ok, dann schauen wir doch mal was für eine Typ das Objekt hat das drin steckt? (wäre, wenn man es programmieren würde s.getClass()). Gibt es da eine Methode print ohne Parameter? Wenn ja => Rufe sie auf. Wenn nein: Dann schau ich mal die Oberklasse an. Gibt es da eine Methode print ohne Parameter? usw. Wenn man am Ende bei Object angekommen ist und es da auch die Methode nicht gibt, wirft die Laufzeitumgebung eine NoSuchMethodException.

Ok, habe ich hoffentlich soweit verstanden.
Konkret:
Beim Aufruf
s.print();
stellt die Laufzeitumgebung fest:
Es gibt im Objekt s die Methode print().
Also wird sie aufgerufen, dh. der folgende Programmcode abgearbeitet:
----------------------------------
System.out.println("Vater_name="+((Vater)this).name);
((Vater)this).print();
-------------------------------------
also wird speziell auch die folgende Anweisung abgearbeitet:
((Vater)this).print();
this ist das Objekt s, also müsste nach deiner Beschreibung ("Algorithmus")
((Vater) s ).print()
aufgerufen werden.
Das wird aber nicht gemacht.
Wo liegt mein Denkfehler ?

mfg
Ern
 

thecain

Top Contributor
Warum erbt Sohn eigtl von Vater bei dir?

Mit einem "korrekteren" Beispiel wäre das Verständnis vll auch einfacher... Ersetze z.b. Vater durch Mensch.

Eine Vererbung ist immer eine "is a" Beziehung. Ein Sohn ist ja kein Vater...
 

ernst

Top Contributor
Warum erbt Sohn eigtl von Vater bei dir?
Mit einem "korrekteren" Beispiel wäre das Verständnis vll auch einfacher... Ersetze z.b. Vater durch Mensch.
Eine Vererbung ist immer eine "is a" Beziehung. Ein Sohn ist ja kein Vater...
Du hast Recht.
Aber die Idee habe ich aus einem guten Buch ("Java als erste Programmiersprache" von Heinisch, Müller-Hofmann, Goll)
Sohn - Vater - Grossvater
soll einfach die Hierarche anzeigen.

mfg
Ern
 

httpdigest

Top Contributor
also wird speziell auch die folgende Anweisung abgearbeitet:
((Vater)this).print();
this ist das Objekt s, also müsste nach deiner Beschreibung ("Algorithmus")
((Vater) s ).print()
aufgerufen werden.
Das wird aber nicht gemacht.
Wo liegt mein Denkfehler ?
Dein Denkfehler liegt darin, zu glauben, dass der Ausdruck:
Java:
((Vater) s ).print()
bedeutet:
"Rufe die Methode print() in Klasse Vater auf dem Objekt in `s` auf."
Das ist FALSCH!
Es wird die print() Methode aufgerufen, die in der Typhierarchie des Laufzeittypen des Objektes in `s` am weitesten überschrieben ist. Der Laufzeittyp des Objektes, das in der Variablen `s` gespeicher ist, ist immer noch Sohn, egal, ob du statisch nach "Vater" castest oder nicht. Und Sohn überschreibst die print() Methode. Somit wird also die print() Methode der Klasse Sohn auf dem Objekt in `s` aufgerufen.
Lies' dir bitte den referenzierten Abschnitt https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.4.4 durch. Dort ist haargenau beschrieben, was bei jedem Aufruf einer virtuellen/überschriebenen Methode passiert.
 

LimDul

Top Contributor
Ok, habe ich hoffentlich soweit verstanden.
Konkret:
Beim Aufruf
s.print();
stellt die Laufzeitumgebung fest:
Es gibt im Objekt s die Methode print().
Also wird sie aufgerufen, dh. der folgende Programmcode abgearbeitet:
----------------------------------
System.out.println("Vater_name="+((Vater)this).name);
((Vater)this).print();
-------------------------------------
also wird speziell auch die folgende Anweisung abgearbeitet:
((Vater)this).print();
this ist das Objekt s, also müsste nach deiner Beschreibung ("Algorithmus")
((Vater) s ).print()
aufgerufen werden.
Das wird aber nicht gemacht.
Wo liegt mein Denkfehler ?
Neben dem was schon erwähnt wurde - Der Cast ist vollkommen egal. Du casted s nach Vater. da gibt es eine Methode print, Haken dran, deswegen kompiliert der Code. Nun soll zur Laufzeit geschaut werden, was aufgerufen wird - und der stellt fest in s ist ein Objekt vom Typ Sohn gespeichert und ruft die Methode der Sohn-Klasse auf.

Java:
((Vater) s)
Ändert nicht das in s gespeicherte Objekt auf eins vom Typ Vater. ist es immer noch ein Objekt vom Typ Sohn. Nur für den Compiler wird gesagt "Behandel es wie ein Vater-Objekt, sprich, stell nur die Methoden für den Compiler zur Verfügung, die Vater bereitstellt.

Du änderst nur die Fassade - hinter der Fassade ist immer noch das gleiche Objekt.
 

Blender3D

Top Contributor
Was ist "die am meisten überschriebene Methode" ?

Mir ist immer noch nicht die Vorgehensweise klar, welches print() ermittelt wird:
Die Variable s hat den Datentyp Sohn und Datentyp Vater.
Problem1:
Welcher Datentyp wird genommen?
Der Typ von dem die Variable ist.
Also:
Java:
[B]s[/B] = new Sohn();
( (Vater)[B] s[/B]).print()
Der Cast auf Vater ändert nichts am Type der Variable s.
Du musst aber zwischen dem Überdecken von Variablen und dem Überschreiben von Methoden unterscheiden.
Java:
(Vater) this).name
Greift auf dem Namen von Vater zu. Die Variable existiert für Sohn 2 x. Vater.name und Sohn.name. Sohn kennt aber nur eine print() Methode.
Durch super.print() kann man auf die print Methode von Vater zugreifen.
Normalerweise macht das Überdecken von Variablen wenig Sinn, da man durch Vererbung eine bestehende Klasse erweitern will durch neue Attribute und neue oder veränderte Methoden. Außerdem führt das zu unübersichtlichem Code welcher name ist gemeint.
Vererbung sollte immer auch semantisch stimmen.
Ein Sohn ist ein Vater ist nicht gerade sinnvoll.
 

ernst

Top Contributor
Der Typ von dem die Variable ist.
Also:
Java:
[B]s[/B] = new Sohn();
( (Vater)[B] s[/B]).print()
Der Cast auf Vater ändert nichts am Type der Variable s.
1)
Gut, dann ändere ich den Quellcode von print() in der Klasse Sohn ab zu:
Code:
        public void print(){
            System.out.println("Vater_name="+((Vater)this).name);
            Vater x;
            x = this;
            x.print();
            //((Vater)this).print();            
        }
Jetzt ist x beim Kompilieren vom Type Vater und während der Laufzeit vom Type Sohn.
Also wird die Methode print() von der Klasse Sohn aufgerufen. Das ist mir jetzt klar.

2)
Hier nochmals der alte Quellcode von der Methode print() der Klasse Sohn:
Code:
        public void print(){
            System.out.println("Vater_name="+((Vater)this).name);
            ((Vater)this).print();            
        }
Wenn man
((Vater)this).print();
aufruft, kann man sich das so vorstellen, dass intern temporär eine "anonyme" Variable a erzeugt wird und intern
a = (Vater)this;
gemacht wird und dann
a.print();
aufgerufen wird.
Jetzt ist a beim Kompilieren vom Type Vater und während der Laufzeit vom Type Sohn.
Also wird die Methode print() von der Klasse Sohn aufgerufen.
So kann ich mir das erklären.
Ist das korrekt?

mfg
Ern
 

Blender3D

Top Contributor
So kann ich mir das erklären.
Ist das korrekt?
1) this verweist immer auf das Objekt selbst.
2) der Cast von Sohn auf Vater funktioniert weil Sohn von Vater erbt
3) Trotz Zuweisung:
Java:
Vater a =(Vater)this;
verweist a immer noch auf das Sohn Objekt .
4) Sohn kennt die Methode print() von Vater nicht mehr weil diese überschrieben wurde. --> Aufruf print() von Sohn
Aber:
Die Attribute werden von Vater geerbt. Sohn kennt sowohl Vater.name als auch Sohn.name Hier wird nicht überschrieben sondern überdeckt.
Daher funktioniert ((Vater) s).name.
 

ernst

Top Contributor
Danke für die Antwort.
Trotzdem nochmals gefragt.
War meine Erklärung korrekt?
Speziell:
Jetzt ist a beim Kompilieren vom Type Vater und während der Laufzeit vom Type Sohn.

mfg
Ern
 

ernst

Top Contributor
Wieso nicht? Tut es doch. Erstmal ist der Ausdruck ((Vater)this) hier völlig unnötig. Du machst einen Upcast zu einem Typ, den das Objekt sowieso selber schon hat und rufst dann eine überschriebene Methode auf. Und der Aufruf einer überschriebenen Methode ruft _immer_ die am meisten überschriebene Methode ausgehend vom Laufzeittyp des Empfängerobjektes auf.
Was ist die am meisten überschriebene Methode ?

mfg
Ern
 

httpdigest

Top Contributor
Was ist die am meisten überschriebene Methode ?
Der Begriff "am meisten" war hier vielleicht nicht ganz sinnvoll. Damit meine ich die Methodenimplementierung, die in der Typhierarchie des jeweiligen Laufzeittypen am "nächsten" zum Laufzeittypen ist. Wenn du also die Typhierarchie A, B extends A, C extends B hast und A und B implementieren die Methode `print()` aber C implementiert print() nicht und der Laufzeittyp des Objektes, auf dem du `print()` aufrufst C ist, dann ist die "am weitesten" überschriebene Methode in Richtung des Laufzeittypen `C` dann B.print(), weil sie in der Typhierarchie A <- B <- C am "nächsten" zum Laufzeittyp C liegt (wo ja die Suche nach der tatsächlich aufzurufenden Methode startet und die Typhierarchie nach oben wandert).
Wenn zum Beispiel auch C die Methode print() implementieren würde, dann wäre die "nächste" Methode `print()` ausgehend von C die Methode C.print(). Und wenn in der Hierarchie A <- B <- C nur A die Methode print() implementieren würde, und du auf einem Objekt vom Typ C die Methode print() aufrufst, dann ist die "nächste" Implementierung der Methode print() in A, ausgehend von C.
 

ernst

Top Contributor
Wenn zum Beispiel auch C die Methode print() implementieren würde, dann wäre die "nächste" Methode `print()` ausgehend von C die Methode C.print(). Und wenn in der Hierarchie A <- B <- C nur A die Methode print() implementieren würde, und du auf einem Objekt vom Typ C die Methode print() aufrufst, dann ist die "nächste" Implementierung der Methode print() in A, ausgehend von C.
Ok, habe ich verstanden.
Das Programm von mir war ein Versuch auf die print() Methode der Oberklasse zuzugrifen, ohne super.print() zu benutzen.
Man könnte jetzt einwenden und sagen. Warum der Aufwand ? Nehm doch super.print().
Was ist aber wenn ich auf die print() Methode der OberOberklasse zugreifen will (in meinem Beispiel müsste ich noch die Klasse Grossvater ergänzen).
super.super.print() geht syntaktisch nicht.
Gibt es eine Möglichkeit auf die print() Methode der OberOberklasse zuzugreifen?

mfg
Ern
 

LimDul

Top Contributor
super.print() ruft die Methode auf, die "überschrieben" wurde.

Das heißt, wenn in der Oberklasse print() nicht überschrieben wurde, dann ruft super.print() die Methode der OberOberklasse auf.
Wenn aber in der Oberklasse print() überschrieben wurde, gibt es keine Möglichkeit direkt die Methode der OberOberklasse aufzurufen. Das widerspricht der Ableitung als "Is A" Prinzip. Denn die Klasse ist eine Ableitung der Oberklasse - das heißt sie muss sich eigentlich wie eine Oberklasse verhalten ggf. noch etwas spezieller. Wenn ich nun die print Methode der Oberklasse umgehe und direkt auf die der OberOberKlasse zugreife verletze ich das Prinzip - den ich sage "Ich will mich an der stelle nicht wie meine Oberklasse verhalten, aber wie meine OberOberKlasse". Und das ist selten sinnvoll - wenn man das machen will, deutet es eher auf schlechte Architektur hin.
 

ernst

Top Contributor
Das widerspricht der Ableitung als "Is A" Prinzip. Denn die Klasse ist eine Ableitung der Oberklasse - das heißt sie muss sich eigentlich wie eine Oberklasse verhalten ggf. noch etwas spezieller. Wenn ich nun die print Methode der Oberklasse umgehe und direkt auf die der OberOberKlasse zugreife verletze ich das Prinzip - den ich sage "Ich will mich an der stelle nicht wie meine Oberklasse verhalten, aber wie meine OberOberKlasse". Und das ist selten sinnvoll - wenn man das machen will, deutet es eher auf schlechte Architektur hin.
Ist die Relation isA nicht transitiv ?
Also
Aus X isA Y Und Y isA Z folgt X isA Z

mfg
Ern
 

LimDul

Top Contributor
Die Relation ja - aber das ist jetzt erst mal nur die Technik.

Ich kann durchaus in Java folgendes schreiben:

Code:
class Auto extends Pferd
Das ist nicht aber fachlich nicht sinnvoll. Der Zugriff auf eine Methode der Ober-Ober-Klasse unter Umgehung einer Methode der Oberklasse ist genauso fachlich nicht sinnvoll - und wird daher unterbunden.[/code]
 

httpdigest

Top Contributor
Die Variable s hat den Datentyp Sohn und Datentyp Vater.
Ist das korrekt ?
Welche Variable `s`? In meinem gequoteten Text referenziere ich auf keine Variable `s`.
Generell ist es aber so, dass eine Variable ein Syntaxelement ist, was statisch ist und auch nur einen Compilezeit-Typ hat. Wenn du z.B. diesen Codeschnipsel hast:
Java:
Oberklasse s = new Unterklasse();
// mit Unterklasse extends Oberklasse
dann hat die Variable `s` den statischen Compilezeittyp `Oberklasse`.
Der Wert bzw. das Objekt, welches von dieser Variablen dann zur Laufzeit gehalten wird, hat in diesem konkreten Fall den (dynamischen) Laufzeittyp `Unterklasse`. Das muss aber nicht so sein. Man kann sich ja auch folgenden Code vorstellen:
Java:
Oberklasse s = gibMirEineInstanz();
und die Methode `gibMirEineInstanz()` könnte ja auch mal eine Instanz von nur Oberklasse zurückliefern.
 

ernst

Top Contributor
Das muss aber nicht so sein. Man kann sich ja auch folgenden Code vorstellen:
Java:
Oberklasse s = gibMirEineInstanz();
und die Methode `gibMirEineInstanz()` könnte ja auch mal eine Instanz von nur Oberklasse zurückliefern.
I)
Ich verstehe dein Beispiel nicht.
Was meinst du damit?

II)
Habe mich auf mein Beispiel bezogen, bei dem s vorgekommen ist. Aber egal. Ich beziehe mich jetzt auf deine Beispiele.
Java:
Oberklasse s = new Unterklasse();
// mit Unterklasse extends Oberklasse
dann hat die Variable `s` den statischen Compilezeittyp `Oberklasse` und nicht den statischen Typ 'Unterklasse'
Ist das richtig ?

Eine Variable kann nur genau einen statischen Typ haben.
Ist das richtig?

Eine Variable kann nur genau einen dynamischen Typ (= dynamischen Laufzeittyp)statischen Typ haben.
Dieser hängt natürlich immer von der Stelle ab, wo sich das Programm gerade befindet.
Ist das richtig?

mfg
Ern
 
K

kneitzel

Gast
Eine Variable ist eine statische Sache. Eine Variable hat damit immer genau einen Typ.

Der Inhalt einer Variable ist aber dynamisch, denn er kann sich ja ständig ändern und daher hat der Inhalt keinen statischen typ sondenr kann dynamisch unterschiedliche Typen haben.

Aber jeder Inhalt hat natürlich wieder genau einen konkreten Typ. Also wenn Du mir new eine Instanz erzeugst, hat diese neue Instanz genau einen typ. (-> getClass gibt die Klasse zurück, getClass().getSimpleName() aufrufen und anzeigen lassen um das evtl. etwas in der Praxis auszuprobieren und zu verstehen.)

Code:
Oberklasse s = new Unterklasse();

Du erzeugst also eine neue Instanz, diese ist vom Typ "Unterklasse" und wird auch nie einen anderen Typ haben.
Du hast eine Variable s vom Typ Oberklasse. Die Variable wird auch immer diesen Typ haben. (Oder hat Java in den neuen Versionen da schon automatische Casts bekommen wie Kotlin? Dass nach eines Typ-Prüfung darauf auch direkt zugegriffen werden kann? Ist aber egal für das grobe Verständnis.)

Der Inhalt der Variable ist aber dynamisch. Denn ich kann da ja ganz viel Neues rein schreiben:

Code:
Oberklasse s = new Unterklasse(); // Danach ist eine Instanz vom Typ Unterklasse in der Variable.
// ...
s = new Oberklasse(); // Jetzt schreiben wir eine Instanz vom Typ Oberklasse in die Variable ...
// ...
 

httpdigest

Top Contributor
I)
Ich verstehe dein Beispiel nicht.
Was meinst du damit?
Mit dem Beispiel `Oberklasse s = gibMirEineInstanz();` meine ich, dass man nicht weiss, welches konkrete Objekt insbesondere von welchem konkreten Laufzeittyp eine Methode zurückgibt. In Fall mit `Oberklasse s = new Unterklasse()` ist es offensichtlich, dass hier eine Instanz von `Unterklasse` erzeugt wird. Aber prinzipiell kann hier auch einfach eine Methode aufgerufen worden sein, die durch beliebige Faktoren/Bedingungen entscheidet, welche konkrete von Oberklasse abgeleitete Instanz zurückgeliefert wird.

Java:
Oberklasse s = new Unterklasse();
// mit Unterklasse extends Oberklasse
dann hat die Variable `s` den statischen Compilezeittyp `Oberklasse` und nicht den statischen Typ 'Unterklasse'
Ist das richtig ?
Korrekt.

Eine Variable kann nur genau einen statischen Typ haben.
Ist das richtig?
Wenn man es genau nehmen möchte, könnte man auch sagen, dass diese Variable ebenfalls den Typ `java.lang.Object` hat, weil ja jede Klasse auch von `java.lang.Object` erbt. Also eine Variable ist auch immer vom Typ jedes Obertyps des direkt an der Variablendeklaration genannten Typs.

Eine Variable kann nur genau einen dynamischen Typ (= dynamischen Laufzeittyp)statischen Typ haben.
Hier verstehe ich den Satzaufbau nicht. Was meinst du mit "einen dynamischen Typ (= dynamischen Laufzeittyp)statischen Typ"?
Eine Variable hat IMMER nur einen statischen Typ.
Das OBJEKT, welches ZUR LAUFZEIT in der Variablen ZU EINEM GEGEBENEN ZEITPUNKT gespeichert ist, hat einen dynamischen Laufzeittyp. Eine Variable (da es sich dabei um ein statisches Programm-/Syntaxkonstrukt handelt) hat niemals einen dynamischen bzw. Laufzeittyp.
 
K

kneitzel

Gast
Wenn man es genau nehmen möchte, könnte man auch sagen, dass diese Variable ebenfalls den Typ `java.lang.Object` hat, weil ja jede Klasse auch von `java.lang.Object` erbt. Also eine Variable ist auch immer vom Typ jedes Obertyps des direkt an der Variablendeklaration genannten Typs.

Also hier werden wir etwas unscharf.

Wenn ich eine konkrete Instanz habe, dann hat diese genau einen Typ. Dieser ist über getClass() klar abzufragen und das ist genau eine Klasse.

Diese eine Klasse hat aber eine Vererbung: Sie erbt von einer anderen Klasse (und wenn nicht, dann ist Object automatisch die Vaterklasse) und es werden ggf. Interfaces implementiert. Wenn ich die Klasse abgefragt habe (getClass() bei einer Instanz, wenn ich nur den Typ habe, dann kann ich Typ.class schreiben, um an die Klasse heran zu kommen), dann kann ich das z.B. abfragen mit getInterfaces() und getSuperclass().
 

ernst

Top Contributor
Wenn man es genau nehmen möchte, könnte man auch sagen, dass diese Variable ebenfalls den Typ `java.lang.Object` hat, weil ja jede Klasse auch von `java.lang.Object` erbt. Also eine Variable ist auch immer vom Typ jedes Obertyps des direkt an der Variablendeklaration genannten Typs.
Da widersprichst du dir (siehe oben):
Denn dann müsste gelten:
dann hat die Variable `s` den statischen Compilezeittyp `Oberklasse` UND den statischen Typ 'Unterklasse'
(siehe oben)!!

Hier verstehe ich den Satzaufbau nicht. Was meinst du mit "einen dynamischen Typ (= dynamischen Laufzeittyp)statischen Typ"?
Du hast recht! Ich habe das Wort statisch vergessen zu löschen!

Deswegen nochmals:
Eine Variable kann nur genau einen dynamischen Typ (= dynamischen Laufzeittyp) Typ haben.
Dieser hängt natürlich immer von der Stelle ab, wo sich das Programm gerade befindet.
Ist das richtig?

mfg
Ern
 
K

kneitzel

Gast
Eine Variable kann nur genau einen dynamischen Typ (= dynamischen Laufzeittyp) Typ haben.
Dieser hängt natürlich immer von der Stelle ab, wo sich das Programm gerade befindet.

Eine Variable hat einen Inhalt von einem Typ. Dieser Typ muss "kompatibel" sein, d.h. bei primitiven Typen muss der Typ stimmen oder es umwandelbar sein. Bei Instanzen muss der Typ überein stimmen oder es eine Superclasse oder Instanz sein. Und der Typ ist dynamisch und hängt davon ab, was vorher zugewiesen wurde. Es ist unabhängig davon, wo du im Code bist. (Wobei Compiler da ggf. optimieren. Aber das ist ein anderes Thema.)

Nehmen wir einfach eine Methode, die abhängig von einer User-Eingabe eine neue Instanz einer Klasse erzeugt. Benutzer gibt ein: Apfel also wird ein Apfel erzeugt und zurück gegeben. Benutzer gibt ein: Auto - also wird ein Auto erzeugt und zurück gegeben. Zurück gegeben wird als ein Object (davon erbt alles direkt oder indirekt).

Eine Variable vom Typ Object kann das Ergebnis speichern, aber was ist denn da nun drin ist? Hängt halt davon ab, was rein getan wurde. Wo im Code du bist spielt keine Rolle. (Also hier z.B. nach der Zuweisung durch eine Methode wie oben beschrieben.)
 

ernst

Top Contributor
Wo im Code du bist spielt keine Rolle. (Also hier z.B. nach der Zuweisung durch eine Methode wie oben beschrieben.)
Nein.
Es sei:
A Unterklasse B und B Unterklasse C

Hier ein Ausschnitt eines Programmas:
-----------
A a;
Bb;
Cc;
a = new A(); // (1)
a = new B(); // (2)
a = new C(); // (3)
-----------

a hat genau den statischen Typ A. Dieser wird beim Kompilieren festgelegt und ist unabhängig davon an welcher Stelle der Programmcode zur Laufzeit gerade abgearbeitet wird.

Der dynamische Laufzeittyp von a hängt natürlich davon ab, ob der Programmcode an der Stelle (1) , (2) oder (3) abgearbeitet wird.

mfg
Ern
 

httpdigest

Top Contributor
Da widersprichst du dir (siehe oben):
Denn dann müsste gelten:
dann hat die Variable `s` den statischen Compilezeittyp `Oberklasse` UND den statischen Typ 'Unterklasse'
(siehe oben)!!
Ich wüsste nicht, wo sich das widerspricht. Ausser der Unschärfe, die @JustNobody richtigerweise angebracht hat, wäre es immer noch nachvollziehbar zu sagen, wenn du hast:
Java:
Oberklasse s = new Unterklasse();
dass der (statische) Typ der Variablen `s` gleich Oberklasse ist UND auch gleichzeitig jeder Obertyp von Oberklasse, also auch java.lang.Object. Das steht nicht im Widerspruch zu vorher Gesagtem.
ABER: Der statische Typ von `s` ist NICHT eine mögliche Subklasse davon. Also insbesondere ist der statische Typ von `s` eben NICHT Unterklasse (was du unterstellt hast und ich nicht behauptet hatte).

Der dynamische Laufzeittyp von a...
Nein. Ein statisches Syntaxelement, wie eben eine Variable, hat keinen dynamischen Laufzeittyp. Der Wert bzw. das Objekt, das in der Variablen gespeichert ist (oder von einem beliebigen statischen Ausdruck generiert wird) hat einen dynamischen Laufzeittyp.
Also:
- Statische Syntaxelemente wie eben eine Variable haben nur einen statischen Compilezeittyp.
- Objekte/Werte, die bei der Ausführung/Evaluierung von Ausdrücken (wie z.B. Variablen) generiert werden, haben dynamische Laufzeittypen.
 

ernst

Top Contributor
Ich wüsste nicht, wo sich das widerspricht. Ausser der Unschärfe, die @JustNobody richtigerweise angebracht hat, wäre es immer noch nachvollziehbar zu sagen, wenn du hast:
Java:
Oberklasse s = new Unterklasse();
dass der (statische) Typ der Variablen `s` gleich Oberklasse ist UND auch gleichzeitig jeder Obertyp von Oberklasse, also auch java.lang.Object. Das steht nicht im Widerspruch zu vorher Gesagtem.
ABER: Der statische Typ von `s` ist NICHT eine mögliche Subklasse davon. Also insbesondere ist der statische Typ von `s` eben NICHT Unterklasse (was du unterstellt hast und ich nicht behauptet hatte).


Nein. Ein statisches Syntaxelement, wie eben eine Variable, hat keinen dynamischen Laufzeittyp. Der Wert bzw. das Objekt, das in der Variablen gespeichert ist (oder von einem beliebigen statischen Ausdruck generiert wird) hat einen dynamischen Laufzeittyp.
Also:
- Statische Syntaxelemente wie eben eine Variable haben nur einen statischen Compilezeittyp.
- Objekte/Werte, die bei der Ausführung/Evaluierung von Ausdrücken (wie z.B. Variablen) generiert werden, haben dynamische Laufzeittypen.

Ich wüsste nicht, wo sich das widerspricht.
1)
Du hast Recht!
Es sei:
A Unterklasse B und B Unterklasse C

Hier ein Ausschnitt eines Programmas:
-----------
A a;
B b;
C c;
c = new C();
-----------
Dann gilt:
Die Variable `c` hat den statischen Compilezeittyp `C und
Die Variable `c` hat den statischen Compilezeittyp `B` und
Die Variable `c` hat den statischen Compilezeittyp `A`.
Ist das richtig?

2)
Es sei:
A Unterklasse B und B Unterklasse C

Hier ein Ausschnitt eines Programmas:
-----------
A a;
B b;
C c;
a = new A(); // (1)
a = new B(); // (2)
a = new C(); // (3)
-----------

a hat genau den statischen Typ A und
a hat nicht den statischen Typ B und
a hat nicht den statischen Typ C.
Der Datentyp von a wird beim Kompilieren festgelegt und ist unabhängig davon an welcher Stelle der Programmcode zur Laufzeit gerade abgearbeitet wird.
Ist das richtig?

Der dynamische Laufzeittyp des Objektes auf das a zeigt hängt davon ab, ob der Programmcode an der Stelle (1) , (2) oder (3) abgearbeitet wird.
Ist das richtig?


mfg
Ern
 
K

kneitzel

Gast
Es hängt NICHT von der Stelle ab. Es hängt von der Zuweisung ab.

Das Beispiel mit der Methode, deren Rückgabe Du nicht kennen kannst, habe ich schon gebracht.

Somit ist die Stelle nicht aussagekräftig. In Deinem trivialen Beispiel ist diese zwar aussagekräftig, aber die Aussage das nach 1 eben eine Instanz von A und nach 2 eine instanz von B in der Variablen a zu finden ist, liegt einfach daran, dass Du eben exakt dies vorher zugewiesen hast. (Und das ist dann auch etwas, wo Compiler dann ggf. Optimierungen machen können und so ....) Daraus leitet sich aber eben nicht eine allgemeine Aussage ab.

a = someMethod();
Nur an der Stelle kannst Du eben NICHT erkennen, was da zur Laufzeit in der Variablen genau drin ist.

Das ist eben das, was @httpdiggest schon in #11 erwähnt und mit einem Link gepostet hat und was Du Dir evtl. noch einmal ansehen solltest.

Aber ja: Der Datentyp einer Variable wird vom Programm festgelegt aber die Unabhängigkeit von der Stelle verstehe ich nicht. Jede Variable hat einen Gültigkeitsbereich. Somit ist die Stelle auch durchaus wichtig.
 

ernst

Top Contributor
Ich verstehe leider deine Antwort nicht.
Kannst du bitte konkret meine Fragen meines Postings beantworten und falls meine Behauptungen falsch sind dazu jeweils ein Gegenbeispiel bringen ?

mfg
Ern
 

temi

Top Contributor
Diskutiert ihr gerade, was der statische und dynamische Typ einer Variablen ist?

Statischer Typ: Ist der Typ einer Variablen, die bei der Variablendeklaration angegeben sind. Dieser Typ ist bei der Kompilierung schon bekannt.

Dynamischer Typ: Ist der Typ einer Variable, welcher erst zur Laufzeit bekannt ist und kann vom statischen Typen abweichen.

Der dynamische Laufzeittyp des Objektes auf das a zeigt hängt davon ab, ob der Programmcode an der Stelle (1) , (2) oder (3) abgearbeitet wird.
Ist das richtig?
Im Prinzip hast du damit Recht, wenn du damit meinst, dass der dynamische Typ davon abhängt, was dieser Variablen zugwiesen wird. Das muss ja nicht immer so eindeutig sein, wie in deinem Beispiel. Der "Inhalt" kann ja auch aus einer anderen Quelle kommen.

Auto auto = autohaus.getCheapestModel(); // da kann dann allerlei dabei rauskommen

Falls ich euer Problem mißverstanden habe, dann bitte ich um Verzeihung und ziehe mich wieder still zurück ;)
 
K

kneitzel

Gast
1)
Du hast Recht!
Es sei:
A Unterklasse B und B Unterklasse C

Hier ein Ausschnitt eines Programmas:
-----------
A a;
B b;
C c;
c = new C();
-----------
Dann gilt:
Die Variable `c` hat den statischen Compilezeittyp `C und
Die Variable `c` hat den statischen Compilezeittyp `B` und
Die Variable `c` hat den statischen Compilezeittyp `A`.
Ist das richtig?

Also das ist nicht richtig. Wenn Du meintest:

Die Variable `c` hat den statischen Compilezeittyp `C und
Die Variable `b` hat den statischen Compilezeittyp `B` und
Die Variable `a` hat den statischen Compilezeittyp `A`.

dann wäre es richtig.

2)
Es sei:
A Unterklasse B und B Unterklasse C

Hier ein Ausschnitt eines Programmas:
-----------
A a;
B b;
C c;
a = new A(); // (1)
a = new B(); // (2)
a = new C(); // (3)
-----------

a hat genau den statischen Typ A und
a hat nicht den statischen Typ B und
a hat nicht den statischen Typ C.
Der Datentyp von a wird beim Kompilieren festgelegt und ist unabhängig davon an welcher Stelle der Programmcode zur Laufzeit gerade abgearbeitet wird.
Ist das richtig?

Der dynamische Laufzeittyp des Objektes auf das a zeigt hängt davon ab, ob der Programmcode an der Stelle (1) , (2) oder (3) abgearbeitet wird.
Ist das richtig?

Ja, das ist richtig, denn bei 1, 2 und 3 werden Zuweisungen gemacht. Der Programmcode, der einer Variable einen neuen Wert zuweist, kann der Variablen eine Referenz auf einen anderen Typen zuweisen.

Ich selbst würde aber nicht von "dynamischem Typ der Variable" sprechen, denn es geht hier ja nicht um den Typ der Variable (Der ist statisch!) sondern um den Typ der gespeicherten Referenz.
 

ernst

Top Contributor
1)
Nochmals zu dem Programm
A Unterklasse B und B Unterklasse C
-----------
A a;
B b;
C c;
c = new C();
-----------
Dann gilt:
Die Variable `c` hat den statischen Compilezeittyp `C und
Die Variable `c` hat den statischen Compilezeittyp `B` und
Die Variable `c` hat den statischen Compilezeittyp `A`.

In dem Buch: "Java als erste Programmierprache" (Heinisch, Müller-Hofmann, Goll) steht (S. 365 der 5.Auflage)
"Ein Objekt der Klasse Sohn ist stets vom Typ Sohn und vom Typ Vater."
(wobei Sohn Unterklasse von Vater ist).
Damit wäre meine Behauptung richtig, oder was meinst du dazu?

2)
Du sagst:
"Ich selbst würde aber nicht von "dynamischem Typ der Variable" sprechen,
denn es geht hier ja nicht um den Typ der Variable
(Der ist statisch!) sondern um den Typ der gespeicherten Referenz."

Der dynamische Laufzeittyp des Objektes auf das a zeigt ....
Das ist doch aber korrekt ausgedrückt, oder was meinst du dazu?

mfg
Ern
 
K

kneitzel

Gast
In dem Buch: "Java als erste Programmierprache" (Heinisch, Müller-Hofmann, Goll) steht (S. 365 der 5.Auflage)
"Ein Objekt der Klasse Sohn ist stets vom Typ Sohn und vom Typ Vater."
(wobei Sohn Unterklasse von Vater ist).
Damit wäre meine Behauptung richtig, oder was meinst du dazu?

Nein, deine Behauptung ist falsch! Du redest von einer Variablen. Das Buch von Objekten, also Instanzen.

Variablen sind Behälter, in denen Du Objekte speichern kannst.

Ein Hund ist ein Säugetier ist ein Lebewesen ist ein Objekt.
Ein Elefant ist auch ein Lebewesen und ein Objekt.

Eine Hundebox nimmt nur Hunde auf. Schäferhund ist ein Hund -> kann also in die Hundebox.

Wenn die Box aber auch vom Typ Säugetier, Lebewesen und Objekt wäre, dann würde der Elephant ja auch da rein passen? Das ist aber nicht so, denn wenn da ein Hund drin ist, will ich ja das Verhalten des Hundes haben. Ich will also bellen() aufrufen können. Das geht aber bei Elefant nicht ...

2)
Du sagst:
"Ich selbst würde aber nicht von "dynamischem Typ der Variable" sprechen,
denn es geht hier ja nicht um den Typ der Variable
(Der ist statisch!) sondern um den Typ der gespeicherten Referenz."

Der dynamische Laufzeittyp des Objektes auf das a zeigt ....
Das ist doch aber korrekt ausgedrückt, oder was meinst du dazu?

Also das sind jetzt sprachliche Feinheiten. Das Problem ist, dass allgemein gerne bei Vererbung von "ist ein" gesprochen wird. Daher ist ein Schäferhund ein Hund, ein Säugetier, ein Lebewesen und ein Objekt.

Und eine Variable, in der ich einen Hund speichern kann, kann alles aufnehmen: Schäferhund, Dackel, Dobermann, ...

Aber wichtig ist: Für eine Instanz ist die Klasse festgelegt. Ein Schäferhund ist und bleibt ein Schäferhund. Der verwandelt sich nicht in einen Dackel oder so...

Dynamisch ist also nur der Inhalt (und mit dem Inhalt kann sich der Typ ändern).

Ich gehe aber davon aus, dass Du das Richtige meinst.
 

ernst

Top Contributor
Nein, deine Behauptung ist falsch! Du redest von einer Variablen. Das Buch von Objekten, also Instanzen.
...
Ich gehe aber davon aus, dass Du das Richtige meinst.
Ich versuche nochmals eure Erklärungen in meine Worte zu fassen.
Es sei:
A Unterklasse B und B Unterklasse C

Hier ein Ausschnitt eines Programmas:
-----------
A a;
B b;
C c;
a = new A(); // (1)
a = new B(); // (2)
a = new C(); // (3)
-----------

1)
Jede Variable hat genau einen statischen Typ.
Also:
Die Variable a hat genau den statischen Typ A und deshalb nicht den statischen Typ B und
nicht den statischen Typ C.
Der Datentyp von a wird beim Kompilieren festgelegt und ist unabhängig davon an welcher Stelle der Programmcode zur Laufzeit gerade abgearbeitet wird.
Frage1:
Ist das richtig?

2)
Der dynamische Laufzeittyp des Objektes auf das a zeigt kann sich während der Laufzeit ändern (je nachdem, was a zugewiesen wurde), wobei das zugewiesene Objekt eine Unterklasse von A sein muss.
Frage2:
Ist das richtig?

mfg
Ern
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Klasse importieren wenn 2 mal gleicher Name Java Basics - Anfänger-Themen 2
V mehrere Instanzen gleicher Name möglich? Java Basics - Anfänger-Themen 3
G XML nächstes Child element (gleicher name) Java Basics - Anfänger-Themen 5
R Größter zusammenhängender Block gleicher Zeichen im String Java Basics - Anfänger-Themen 1
K Java gleicher Wert von Zahlen? Java Basics - Anfänger-Themen 5
B bei 2 Arrays Anzahl gleicher Elemente vergleichen? Java Basics - Anfänger-Themen 49
E JPanels auf gleicher Höhe (Y-Achse) in einem FlowLayout platzieren Java Basics - Anfänger-Themen 7
M In gleicher zeile hinter ausgabe noch etwas ausgeben Java Basics - Anfänger-Themen 1
L Best Practice Code Refactoring für Methoden mit fast gleicher Aufbau Java Basics - Anfänger-Themen 6
L Zwei sortierte Subarrays mit gleicher Länge zusammenfügen Java Basics - Anfänger-Themen 2
J Unterschiedliche Ordnerstrukturen trotz gleicher Entwicklungsumgebungen Java Basics - Anfänger-Themen 3
H Würfelspiel, stop bei gleicher Zahl Java Basics - Anfänger-Themen 4
K Anzahl gleicher Elemente in Array Java Basics - Anfänger-Themen 32
B Gleicher Prozess starten und stoppen (Problem beim Stoppen) Java Basics - Anfänger-Themen 5
B Klassen HashMap Zwei Objekte, gleicher Key Java Basics - Anfänger-Themen 4
N Compiler findet array in gleicher methode nicht Java Basics - Anfänger-Themen 4
D Ermitteln der Anzahl gleicher Nachkommastellen 2er Zahlen Java Basics - Anfänger-Themen 9
? Algo gleicher Buchstabe in 2 Wörtern suchen Java Basics - Anfänger-Themen 16
I Array und variable gleicher wert, wird jedoch nicht erkannt Java Basics - Anfänger-Themen 4
R Anzahl gleicher Elemente in ArrayList Java Basics - Anfänger-Themen 5
G Gleicher Klassenname in API Java Basics - Anfänger-Themen 2
G in Verzeichnis auf gleicher Ebene wechseln Java Basics - Anfänger-Themen 4
G Abstrakte Methode in gleicher Klasse aufrufen Java Basics - Anfänger-Themen 5
J Jedes Element in 2 Arrays mit gleicher Position addieren Java Basics - Anfänger-Themen 12
X trotz gleicher variablen nicht equal Java Basics - Anfänger-Themen 5
A PHP $_POST["name"] in Java Java Basics - Anfänger-Themen 3
B JaxB - Unique Name updaten / Referenzen in XML Java Basics - Anfänger-Themen 0
R Call-by-Value, Call-by-Reference, Call-by-Name Ausgabe Java Basics - Anfänger-Themen 1
F Auto String mit Array Name aus Datei... oder so ähnlich Java Basics - Anfänger-Themen 4
B Name von Verzeichnis bekommen - Files von einem Ordner auslesen Java Basics - Anfänger-Themen 4
K File-Name Vergleich Java Basics - Anfänger-Themen 2
J javax.servlet.ServletException: Name is null Java Basics - Anfänger-Themen 7
D jsoup get class name mit leerzeichen Java Basics - Anfänger-Themen 7
J ArrayList Name mit String erstellen Java Basics - Anfänger-Themen 8
B Get property field von Name Java Basics - Anfänger-Themen 9
D Name eines JMenue als Parameter übergeben Java Basics - Anfänger-Themen 20
M Objekt Name für MethodenAufruf nachträglich zuweisen? Java Basics - Anfänger-Themen 2
W DNS Name auslesen + weitere Anfängerfrage Java Basics - Anfänger-Themen 4
L Name im Array suchen Java Basics - Anfänger-Themen 12
K Mit Scanner aus einer txt Datei lesen und jede Person mit name, vorname, geburtsdatum speichern Java Basics - Anfänger-Themen 5
M Name der Komponete/Variabel/Methode Java Basics - Anfänger-Themen 5
I Spieler Name eintragen und Random Gewinner Java Basics - Anfänger-Themen 4
D Taskmanager Name Java Basics - Anfänger-Themen 2
I JTree, Root-Name ändern Java Basics - Anfänger-Themen 4
T Erste Schritte Elemente finden, deren Name erst "zusammengesetzt" wird Java Basics - Anfänger-Themen 8
S Vererbung Fehlermeldung: the hierarchy of the type "class name" is inconsistent Java Basics - Anfänger-Themen 10
D Name einer Variable als String nutzen Java Basics - Anfänger-Themen 13
T Name des Objektes OOP Java Basics - Anfänger-Themen 4
O String name mit fortlaufender Nummer Java Basics - Anfänger-Themen 14
Y ENUM auslesen (Name des ENUM als Variable) Java Basics - Anfänger-Themen 4
S Name eines boolean ausgeben (nicht den Wert) Java Basics - Anfänger-Themen 43
D Mysql schauen Name bereits existiert Java Basics - Anfänger-Themen 7
E Java Name von Exe festlegen? Java Basics - Anfänger-Themen 7
T brauche den pfad Name! Java Basics - Anfänger-Themen 2
F String-Inhalt als Datatype-Name Java Basics - Anfänger-Themen 5
D Methode anhand deren Name aufrufen Java Basics - Anfänger-Themen 4
N Name zu sehr ähnlich??? Java Basics - Anfänger-Themen 12
K Datentypen Full qualified Name dynamisch gestalten Java Basics - Anfänger-Themen 7
E Welcher Package Name bei Eclipse/Android? Java Basics - Anfänger-Themen 2
H2SO3- name der klasse ausgeben Java Basics - Anfänger-Themen 6
-horn- public static double[][][] NAME() nur per RETURN Wertrückgabe möglich? Java Basics - Anfänger-Themen 20
Z objekt erstellen von canonical name einer klasse Java Basics - Anfänger-Themen 6
O DocumentListener -> Name des JTextFields bekommen Java Basics - Anfänger-Themen 2
J Parameter (Methode) -> Name eines Objekt Java Basics - Anfänger-Themen 3
G Name der Instanz einer Klasse. Java Basics - Anfänger-Themen 2
X Der Name des jars finden? Java Basics - Anfänger-Themen 8
J Objekt-name in Array speichern Java Basics - Anfänger-Themen 12
B jar name ermitteln Java Basics - Anfänger-Themen 6
X Ordner mit Tageszeit als Name anlegen Java Basics - Anfänger-Themen 5
J ArrayListen mit Name und Vater an JTree übergeben Java Basics - Anfänger-Themen 3
T Rechner-Name abfragen Java Basics - Anfänger-Themen 6
K java.lang.NoClassDefFoundError: Klasse (wrong name... Java Basics - Anfänger-Themen 17
A String Array: Suche nach Name -> Wert? Java Basics - Anfänger-Themen 3
G name vom objekt Java Basics - Anfänger-Themen 8
B Name und PLZ begrenzen Java Basics - Anfänger-Themen 3
K Objekte erstellen, wenn der Klassen-Name als String vorliegt Java Basics - Anfänger-Themen 4
D Name eines Terminals herausfinden Java Basics - Anfänger-Themen 3
M Kette- oder der Java Name Java Basics - Anfänger-Themen 2
G Name von java-Dateien, *.java Java Basics - Anfänger-Themen 9
G Name einlesen Java Basics - Anfänger-Themen 15
B Woher kommt der Name Java? Java Basics - Anfänger-Themen 4
O viele Name mit jeweils zugehörigen Status in .txt Speichern Java Basics - Anfänger-Themen 16
T System.getProperty("os.name") Java Basics - Anfänger-Themen 13
G File Name Case Sensitive Java Basics - Anfänger-Themen 2
R Welche Componente (Name)? Java Basics - Anfänger-Themen 2
S Variabler Name für ein Objekt einer Klasse? Java Basics - Anfänger-Themen 10
X Property user.name über Konsole verändern Java Basics - Anfänger-Themen 6
F Array Unterschied Typ name[] Typ[] name Java Basics - Anfänger-Themen 7
D Name eines Objekts ermitteln Java Basics - Anfänger-Themen 5
L Name für Objekt übergeben Java Basics - Anfänger-Themen 3
M Vererbung Funktionen in Basisklasse deklarieren Java Basics - Anfänger-Themen 4
S Vererbung Zugriff auf die Basisklasse einer "zweiten" Erweiterungsklasse Java Basics - Anfänger-Themen 2
S Vererbung Array aus Basisklasse bilden? Java Basics - Anfänger-Themen 5
H Abstrakte Basisklasse Verständnisproblem! Java Basics - Anfänger-Themen 8
J Vererbung Zugriff auf die Basisklasse Java Basics - Anfänger-Themen 4
A Aufruf von Konstruktor aus Basisklasse Java Basics - Anfänger-Themen 7
J Vererbung Frage zu Basisklasse Java Basics - Anfänger-Themen 6
P Vererbung Basisklasse soll eigene Methode benutzen Java Basics - Anfänger-Themen 38
F OOP von Basisklasse in Kindklasse umwandeln Java Basics - Anfänger-Themen 9
K feld von basisklasse ändern Java Basics - Anfänger-Themen 11

Ähnliche Java Themen

Neue Themen


Oben