Statischer und Dynamischer Typ

ocsme

Top Contributor
Guten Tag,
hab ein Problem mit dem Statischen und Dynamischen Typ bei der Vererbung.
Hier mal ein Code Beispiel:
Code:
public class A{
public static int x=1;
    public A() {
        x+=3;
    }
    public int f(int y) {
        return y+x;
    }
    public int f(double y) {
        x=0;
        return (int)y;
    }   
}

public class B extends A {
    public int y=3;
    public B(int x) {
        super();
        y+=x;
    }
    public int f(double x) {
        y+=1;
        return (int)x*y;
    }
       
}

Nun soll man schauen was bei folgendem raus kommt:
Java:
A a = new B(2);
    System.out.println(A.x+" "+((B)a).y);
    int z=a.f(4.5);
    System.out.println(((B)a).y+" "+z+" "+A.x);
    B b = (B) a;
    z = b.f(5);
    System.out.println(b.y+" "+z+" "+A.x);

Dachte eigentlich ich hätte es verstanden doch nichts habe ich! :mad:

1. Wieso muss a so gecastet werden ((B)a)? Der Statische Typ ist doch A und der Dynamische Typ ist B damit schaut er doch in der Variable a erst mal in der Classe von B nach oder etwa nicht? dort sollte er das Datenelement finden.
2. a.f(4.5) sollte er auch in der Classe von B nachschauen da das ja der Dynamsche Typ ist und die Methode dort gefunden wird.
3. B b = (B)a was passiert hier genau? Denn ich hätte gesagt das wäre equivalent zu B b = new B(2); also von oben A a = new B (2); ich presse den Dynamischen Typ B in den Statischen Typ B also B = B!!! scheint aber auch Falsch zu sein den eclipse zeigt mir dann auch Methoden von A an :(
4. Welche Funktion wird dann bei z = b.f(5) aufgerufen das sollte sich mit 3. erklären lassen :D

Die 4 Fragen hätte ich zu dieser Aufgabe denn ich verstehe jetzt nichts mehr :eek:

LG
 

httpdigest

Top Contributor
1.: Der statische Typ der Variablen `a` ist `A` und der dynamische Typ des Objektes, welches in der Variablen `a` gespeichert ist, ist `B`. Aber bei Feld- bzw. Instanzvariablenzugriffen findet kein dynamic Dispatch statt - nur bei Methodenaufrufen! Das heißt, es muss zur Compilezeit feststehen, welches `a` aus welcher Klasse du da ganz genau meinst. Und, wenn du eben auf das `a` von `B` statt von `A` zugreifen willst, dann musst du `B` als statischen Typ nutzen.
2.: Korrekt. Hier wird er zur Laufzeit die überschriebene f(double) Methode in `B` aufrufen.
3.: Hier passiert genau dasselbe, was auch bei `((B)a)` passierte. Nur, dass hier der statische Typ des Ausdrucks auch nochmal für eine Variable verwendet wird, der `a` zugewiesen wird. Das heißt, jetzt gibt es eine Variable, deren statischer Typ `B` ist und die dasselbe Objekt enthält, das auch die Variable `a` vorher enthielt. Da wird aber kein Konstruktor aufgerufen, also es wird hier allein durch den bloßen Cast kein neues `B` Objekt erzeugt! Es wird nur der Compilezeittyp festgesetzt/geändert auf `B`.
4.: 3. erklärt das nicht. Es wird hier die nicht-überschriebene Überladung f(int) der Klasse A aufgerufen.
 

ocsme

Top Contributor
Ich danke dir aber ich verstehe es trozdem immer noch nicht so richtig!
Werde mir das morgen erneut anschauen

LG

PS: wieso kann ich wenn ich ein Getter int getY(){return y;} in die Klasse B schreibe ihn mit a.getY() nicht aufrufen?
 

httpdigest

Top Contributor
Merk' dir einfach erstmal folgendes: Ausdrücke haben immer nur statische Typen. Objekte (die durch die Auswertung von Ausdrücken entstehen) haben dynamische Typen.
wieso kann ich wenn ich ein Getter int getY(){return y;} in die Klasse B schreibe ihn mit a.getY() nicht aufrufen?
Alle Ausdrücke müssen einen klaren/definierten statischen Typen haben. Da es in der Klasse `A` (welches ja der statische Typ von `a` ist) keine solche Methode `getY()` gibt, weiß der Compiler nicht, was er jetzt machen soll und von welchem statischen Typen denn das Ergebnis von `getY()` wäre. Das heißt, selbst bei normalerweise dynamic dispatch'ten Methodenaufrufen muss immer trotzdem der statische Typ bekannt sein.
 

ocsme

Top Contributor
Dank dir :)
Jetzt ist mir das ganze erneut Klarer geworden. Werde mich morgen aber wieder hin setzen und das ganze wieder nachlesen.
Bis jetzt hatte ich nur Übungen gemacht in denen Methoden von Vererbten Klassen aufgerufen wurden da hatte ich solche Probleme nicht.
Nochmals Danke httpdigest. Falls ich morgen weiter Fragen habe melde mich erneut :)

LG
 

Meniskusschaden

Top Contributor
aber ich verstehe es trozdem immer noch nicht so richtig!
Man kann es sich vielleicht leichter vorstellen, wenn das Objekt nicht direkt rechts vom Gleichheitszeichen mit new erzeugt wird, sondern von irgendwo anders geliefert wird. Dann wird deutlicher, dass der Compiler nur wissen kann, dass es zwar ein A ist, aber nicht notwendigerweise gleichzeitig ein B.

In folgendem Beispiel ist klar, dass der Compiler mb() und mc() nicht aufrufen kann:
Java:
import java.util.Random;

public class Main {

    public static void main(String[] args) {
        A a = instantiateSubtypeOfA();
        a.ma();
    //  a.mb();
    //  a.mc();
    }

    private static A instantiateSubtypeOfA() {
        return new Random().nextBoolean() ? new B() : new C();
    }
}

class A {
    public void ma() {}
}

class B extends A {
    public void mb() {}
}

class C extends A {
    public void mc() {}
}
 

ocsme

Top Contributor
Ich danke euch nochmals viel mal :)
Denke das ich es nun soweit verstanden habe.
Hab mal wieder eine kleine Datenstruktur geschrieben über Luftfahrzeuge :D
Dort hat man eine Aufgabe man soll eine Methode schreiben, die Methode erhält ein Array von Luftfahrzeugen als Paramter übergeben, daraus ermittelt man die Anzahl der Düsenflugzeuge im Array bei denen die Anzahl an Besatzungsmitgliedern genau eines ist und die zugleich mit Überschallgeschwindigkeit fliegen.

Das Düsenflugzeug ist abgeleitet von Luftfahrzeug. Diese Klasse habe ich so geschrieben:
Java:
public class Luftfahrzeug {

    protected int besatzungsMittglied;
    protected String name;
   
    public int getBesatzungsMittglied() {
        return besatzungsMittglied;
    }
   
    public void setbesatzungsMittglied(int besatzungsMittglied) {
        this.besatzungsMittglied=besatzungsMittglied;
    }
   
    public String toString() {
        return name;
    }
}

das Düsenflugzeug sieht wie folgt aus:
Java:
public class Duesenflugzeug extends Luftfahrzeug implements SchwererAlsLuft{
   
    private boolean ueberschall;
   
    Duesenflugzeug() {
        name="Duesenflugzeug";
        int k=(int)(Math.random()*2+1);
        if(k==1) {
            setbesatzungsMittglied(k);
            int a=(int)(Math.random()*2+1);
            ueberschall=(a==1)?true:false;
        }
            else {
                setbesatzungsMittglied((int)(Math.random()*10+1));
                int a=(int)(Math.random()*2+1);
                ueberschall=(a==1)?true:false;
            }
    }
    public boolean getUeberschall() {
        return ueberschall;
    }
   
    public void setUeberschall(boolean ueberschall) {
        this.ueberschall=ueberschall;
    }

    public void lenkbar(double winkel) {
       
    }
}

Nun habe ich in der main ein Array gefühlt mit Flugzeugen. Danach suche ich wie oben beschrieben die Düsenflugzeuge raus. Ich überprüfe mit instanceof erst einmal ob ich aus Luftfahrzeug ein Düsenflugzeug gefunden habe danach kann ich aus dem Statischen Typ Luftfahrzeug casten und der Compiler sieht die Methoden von Düsenflugzeug :)

Java:
Luftfahrzeug[] liste = new Luftfahrzeug[10];
        befuehllenZufall(liste);
       
       
        for(int i=0;i<liste.length;i++) {
            if(liste[i] instanceof Duesenflugzeug) {
                System.out.println(((Duesenflugzeug)liste[i]).getUeberschall()+" "+((Duesenflugzeug)liste[i]).getBesatzungsMittglied());

            }

Ich weiß das das ganze unvollständig ist und der gleichen es geht mir nur darum das ich verstehe wie es geht mit der Vererbung ;)
Kann nur hoffen das ich es nun soweit richtig verstanden habe :)

LG
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L Polymorphie Dynamischer oder Statischer Typ für Methodenparameter Java Basics - Anfänger-Themen 8
T Unterschied dynamischer und statischer Laufzeittyp Java Basics - Anfänger-Themen 1
W Dynamischer und statischer Typ von Referenzvariablen Java Basics - Anfänger-Themen 13
N Variable aus anderen Variablen in statischer Klasse berechnen/abspeichern? Java Basics - Anfänger-Themen 4
H Polymorphie Interfaces und statischer Typ Java Basics - Anfänger-Themen 33
C Statischer Typ aber Variable nicht statisch? Java Basics - Anfänger-Themen 5
G Polymorphie, Vererbung, statischer Typ, Laufzeittyp Java Basics - Anfänger-Themen 2
I Statischer Initializer Java Basics - Anfänger-Themen 4
kilopack15 this.v mit statischer Variable v? Java Basics - Anfänger-Themen 1
M Input/Output tcp-Server mit statischer Parallelität Java Basics - Anfänger-Themen 7
W If_Bedingung in statischer Methode beim zweiten Mal nicht durchlaufen Java Basics - Anfänger-Themen 14
N Initialisierer / statischer Initialisierer verstehen Java Basics - Anfänger-Themen 6
C Methoden Rückgabewert von statischer Methode ignorieren Java Basics - Anfänger-Themen 8
N ArrayList verwenden in statischer Methode Java Basics - Anfänger-Themen 2
R Frage zu statischer Methode toString() Java Basics - Anfänger-Themen 3
Luk10 Problem mit Singleton bzw statischer Referenz! Java Basics - Anfänger-Themen 16
C Seitenwechsel in statischer Methode? Java Basics - Anfänger-Themen 6
P Statischer Import - ich raffs nicht! Java Basics - Anfänger-Themen 3
H Unterschied statischer/dynamische Typ einer Variablen Java Basics - Anfänger-Themen 2
H statischer Zugriff / accessed in a static way Java Basics - Anfänger-Themen 3
Paule Aufruf nicht statischer Methode in statischer MEthode Java Basics - Anfänger-Themen 7
D statischer Konstruktor Java Basics - Anfänger-Themen 9
G Bei dynamischer Arrayliste nach jeder Auswahl Zahl entfernen Java Basics - Anfänger-Themen 3
J Objekt-Array dynamischer Länge aus Benutzereingaben erstellen Java Basics - Anfänger-Themen 6
S Ein Bild mit dynamischer Quelle neuzeichnen Java Basics - Anfänger-Themen 12
C Input/Output Dynamischer Output von Arrays Java Basics - Anfänger-Themen 3
D dynamischer Aufruf Java Basics - Anfänger-Themen 2
C Datentypen Array mit dynamischer Länge? Java Basics - Anfänger-Themen 14
J Verschachtelte for schleife mit dynamischer Anzahl an Schleifen Java Basics - Anfänger-Themen 10
N "Dynamischer" Iterator Java Basics - Anfänger-Themen 21
G Dynamischer Methodenaufruf Java Basics - Anfänger-Themen 3
T Dynamischer JTabbedPane Probleme mit JTextArea Java Basics - Anfänger-Themen 2
G [Hibernate] Dynamischer Datenbankpfad Java Basics - Anfänger-Themen 4
S Fehler nach dynamischer Anpassung - Minesweeper Java Basics - Anfänger-Themen 6
V Dynamischer Klassen bzw. Methodenaufruf Java Basics - Anfänger-Themen 6
H statische, dynamischer Typ von Variablen Java Basics - Anfänger-Themen 1
B Dynamischer Filename Java Basics - Anfänger-Themen 3
M Variabler/dynamischer Objektname? Java Basics - Anfänger-Themen 12

Ähnliche Java Themen

Neue Themen


Oben