Referenz und Instanzierung

Java4win

Aktives Mitglied
Hey,
Ich habe irgendwo mal gelesen das es auch möglich ist eine Instanzierung so durchzuführen.

Java:
Auto bmw = new Fahrzeuge();

Ich kannte jedoch bisher nur immer diese Instanzierung:

Java:
Auto bmw = new Auto();

Also wo genau liegt hier der Unterschied und was passiert hier genau ?

Vielen Dank im Voraus.
 
Erkennst du denn selbst irgendeinen Unterschied in den beiden Codebeispielen?
Eventuell wird bei dem
Java:
Auto bmw = new Auto();
nur der Konstruktor der Auto Klasse aufgerufen

und bei

Java:
Auto bmw = new Fahrzeuge();
der Konstruktor von der Klasse Auto und von der Klasse Fahrzeuge ?

Aber kann auch sein das ich komplett falsch liege...
 
Java:
Auto bmw = new Fahrzeuge();
funktioniert dann, wenn Auto eine Oberklasse von Fahrzeuge ist. Umgangssprachlich ausgedrückt: wenn jedes Fahrzeuge ein Auto, aber nicht jedes Auto eine Fahrzeuge ist. Wenn der von dir gezeigte Code tatsächlich kompiliert, kann man daraus eine Vererbungshierachie ableiten, die genauso sinnvoll ist wie mein vorangehenden Satz.
 
Jep. Zuerst der von Fahrzeuge, dann der von Auto.
Wird ein Parameterloser Konstruktor aufgerufen von der Klasse Auto ?
Wir haben doch nur dann die Möglichkeit dem Konstruktor der Klasse Fahrzeuge Parameter zu übergeben oder nicht ?

Bearbeitet:
Ich habe mir noch einmal Gedanken gemacht und man könnte doch mit dem Schlüsselwort super in der Klasse Fahrzeuge den Konstruktor aus der Superklasse Parameter über geben oder ?
 
Zuletzt bearbeitet:
Wir haben doch nur dann die Möglichkeit dem Konstruktor der Klasse Fahrzeuge Parameter zu übergeben oder nicht ?
Wenn es einen solchen Konstruktor in der Fahrzeug-Klasse gibt.
man könnte doch mit dem Schlüsselwort super in der Klasse Fahrzeuge den Konstruktor aus der Superklasse Parameter über geben
Wenn es einen Konstruktor der Auto-Klasse mit den entsprechenden Parametern gibt, dann ja.
Näheres zum Thema s. https://www.java-forum.org/thema/code-verstaendnis.178367
 
Sollte auch keine Bestrafung sein. 😉 Aber wenn der Wissende nicht gerade schläft, fallen ihm "Fehler" auf. 😉
"Zuerst" ist auch nicht der richtige Begriff, wenn Auto noch weitere Oberklassen bis zu Object hat. Weiterhin wie angemerkt ist hier confusing naming, denn idR ist ein Auto ein Fahrzeug (nicht vice versa). Kann aber auch aus einer Prüfung eine "Fangfrage" sein.
 
Jep. Zuerst wird der Konstruktor der Superklasse aufgerufen, dann erst der Konstruktor der aktuellen Klasse.
Hm, ist das wirklich so? Muß man hier nicht zwischen "aufgerufen werden" und "ausgeführt werden" unterscheiden? Nach meinem Verständnis wird zuerst der Konstruktor der Subklasse aufgerufen. Dort befindet sich als erstes die Anweisung super(); (ggf. nur implizit), die den Konstruktor der Superklasse aufruft. Nachdem der Supertyp-Konstruktor fertig ist, setzt der Subtyp-Konstruktor seine Arbeit fort.

Demnach würde also zuerst der Subtyp-Konstruktor aufgerufen, aber trotzdem zuerst der Supertyp-Konstruktor ausgeführt werden. Ich weiß nicht sicher, ob es sich wirklich so verhält, aber zumindest habe ich es mir immer so erklärt und es erscheint mir plausibel.
 
Sodele, als Rehabilitation für mein Geschreibsel weiter oben hier noch was zum Thema:
Das implizite Aufrufen des Superklassen-Konstruktors kann durch einen expliziten Aufrufen eines beliebigen Konstruktors der Superklasse unterbunden werden. Der implizite Aufruf setzt voraus, dass die Superklasse einen parameterlosen Konstruktor hat. Wenn in der Superklasse gar kein Konstruktor definiert ist, wird automatisch ein parameterloser Konstruktor erzeugt (sog. Default-Konstruktor). Sobald ein Konstruktor definiert wird, wird der default-Konstruktor nicht mehr automatisch erzeugt. Wenn aber dennoch durch einen impliziten Superklassen-Konstruktoraufruf aus einer abgeleiteten Klasse ein parameterloser KOnstruktor gefordert ist, muss er extra geschrieben werden.
Das hier kompiliert nicht:
Java:
public class Constructors {

    static class Parent {

        Parent(String text) {
            System.out.println("Parent");
        }
    }

    static class Child extends Parent {

        public Child() {
            //Impliziter Aufruf von super(), schlägt fehl, weil Parent keinen solchen Konstruktor hat
            System.out.println("Child");
        }

    }
}
Das hier kompiliert:
Java:
public class Constructors {

    static class Parent {

        Parent(String text) {
            System.out.println("Parent");
        }
    }

    static class Child extends Parent {

        public Child() {
            //Expliziter Aufruf eines Superklassen-Konstruktors
            super(null);
            System.out.println("Child");
        }

    }
}
und das hier auch.
Ausgabe:
Parent ohne Parameter
Child

Java:
public class Constructors {

    public static void main(String[] args){
        new Child();
    }
    static class Parent {

        Parent(String text) {
            System.out.println("Parent");
        }
        Parent(){
            System.out.println("Parent ohne Parameter");
        }
    }

    static class Child extends Parent {

        public Child() {
            //Impliziter Aufruf des parameterlosen Superklasse-Konstruktors
            System.out.println("Child");
        }

    }
}
 
kann durch einen expliziten Aufrufen eines beliebigen Konstruktors der Superklasse unterbunden werden.
ersetzt werden. Zudem: Wenn kein default Konstruktor gegeben ist, wird man gezwungen, einen der Konstruktors aufzurufen.

Zudem: Von dem Beispiel den Bytecode ansehen, um die Aufruferreihenfolge zu sehen.
 
Ich habe eines der Beispiele von @Harry Kane mal so abgewandelt:
Java:
public class Constructors {

    static class Parent {
        Parent() {
            System.out.println("Parent");
        }
    }

    static class Child extends Parent {
        public Child() {
            System.out.println("Child");
        }
    }
  
    public static void main(String[] args) {
        new Child();
    }
  
}
Ausgabe:
Code:
Parent
Child
Bytecode der Klasse Constructors:
Code:
// Compiled from Constructors.java (version 1.8 : 52.0, super bit)
public class Constructors {
 
  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public Constructors();
    0  aload_0 [this]
    1  invokespecial java.lang.Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 2]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: Constructors
 
  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 1, Locals: 1
  public static void main(java.lang.String[] args);
    0  new Constructors$Child [16]
    3  invokespecial Constructors$Child() [18]
    6  return
      Line numbers:
        [pc: 0, line: 17]
        [pc: 6, line: 18]
      Local variable table:
        [pc: 0, pc: 7] local: args index: 0 type: java.lang.String[]

  Inner classes:
    [inner class info: #16 Constructors$Child, outer class info: #1 Constructors
     inner name: #24 Child, accessflags: 8 static],
    [inner class info: #25 Constructors$Parent, outer class info: #1 Constructors
     inner name: #27 Parent, accessflags: 8 static]
}
Bytecode der Klasse Parent:
Code:
// Compiled from Constructors.java (version 1.8 : 52.0, super bit)
static class Constructors$Parent {
 
  // Method descriptor #6 ()V
  // Stack: 2, Locals: 1
  Constructors$Parent();
     0  aload_0 [this]
     1  invokespecial java.lang.Object() [8]
     4  getstatic java.lang.System.out : java.io.PrintStream [10]
     7  ldc <String "Parent"> [16]
     9  invokevirtual java.io.PrintStream.println(java.lang.String) : void [18]
    12  return
      Line numbers:
        [pc: 0, line: 5]
        [pc: 4, line: 6]
        [pc: 12, line: 7]
      Local variable table:
        [pc: 0, pc: 13] local: this index: 0 type: Constructors.Parent

  Inner classes:
    [inner class info: #1 Constructors$Parent, outer class info: #31 Constructors
     inner name: #17 Parent, accessflags: 8 static]
}
Bytecode der Klasse Child:
Code:
// Compiled from Constructors.java (version 1.8 : 52.0, super bit)
static class Constructors$Child extends Constructors$Parent {
 
  // Method descriptor #6 ()V
  // Stack: 2, Locals: 1
  public Constructors$Child();
     0  aload_0 [this]
     1  invokespecial Constructors$Parent() [8]
     4  getstatic java.lang.System.out : java.io.PrintStream [10]
     7  ldc <String "Child"> [16]
     9  invokevirtual java.io.PrintStream.println(java.lang.String) : void [18]
    12  return
      Line numbers:
        [pc: 0, line: 11]
        [pc: 4, line: 12]
        [pc: 12, line: 13]
      Local variable table:
        [pc: 0, pc: 13] local: this index: 0 type: Constructors.Child

  Inner classes:
    [inner class info: #1 Constructors$Child, outer class info: #31 Constructors
     inner name: #17 Child, accessflags: 8 static],
    [inner class info: #3 Constructors$Parent, outer class info: #31 Constructors
     inner name: #33 Parent, accessflags: 8 static]
}
Der Child-Konstruktor ruft also den Parent-Konstruktor auf, welcher den Object-Konstruktor aufruft.
 
Was meinstn damit? Bzw. Inwiefen enthält dieser Satz zusätzliche Informationen
Ich habe wirklich keine Lust, der Nachredner oder Hampelmann zu sein.

Folgendes kompiliert NICHT:
Java:
class Elter {
    Elter(String string) {

    }
}

class Kind extends Elter {

}

Grund:
Code:
constructor Elter in class Elter cannot be applied to given types;
  required: String
  found: no arguments
... und noch ein bisschen Blabla, der jetzt nur verwirren würde
 
@Meniskusschaden und @Harry Kane : Dann stimmen meine Antworten doch....... aber nur @Harry Kane bekommt Likes....... Ungerecht!

Ich schreibe hier auch nicht alles, denn wir verstehen das ja, der TE versteht es nicht. 😕

+++ Also es gibt das, was ("zuerst") aufgerufen wird, und es gibt das, was ausgeführt wird. +++
 
@Meniskusschaden und @Harry Kane : Dann stimmen meine Antworten doch
Ich habe ja auch nicht behauptet, dass du unrecht hast. Du hast hier:
Zuerst der von Auto, dann der von Fahrzeug. Zum Fremdschämen hier...
ja offen gelassen, ob du aufrufen oder ausführen meinst. Der von @Harry Kane gesetzte Kontext war zu diesem Zeitpunkt zwar "Aufrufen", aber es wäre doch etwas kleinkariert, dein Statement deshalb als falsch zu deklarieren. Ich wollte den Sachverhalt nur verdeutlichen (und bei der Gelgenheit selbst heraus finden, ob meine bisherige Meinung überhaupt stimmt).

aber nur @Harry Kane bekommt Likes....... Ungerecht!
Was deine like-Quote angeht, so kam es bei mir schon häufiger vor, dass ich einen fachlich guten Beitrag von dir nicht geliked habe, weil irgendwelche Zusatzbemerkungen enthalten waren, mit denen ich nicht in Verbindung gebracht werden wollte.😉
 
Naja, ich dachte, bei Verzicht auf provokante Formulierungen und Fragen, und bereitwilliges Zugeben des eigenen Fehlers liesse sich womöglich eine professionelle Diskussionsatmosphäre schaffen.
Seis drum. Wenn er glaubt sich mit seiner Art einen Gefallen zu tun, soll er doch.
 

Neue Themen


Zurück
Oben