JavaRush /Java-Blog /Random-DE /Klassenkonstruktoren. Java JDK 1.5
articles
Level 15

Klassenkonstruktoren. Java JDK 1.5

Veröffentlicht in der Gruppe Random-DE
Klassenkonstruktoren.  Java JDK 1.5 - 1

Allgemeine Informationen zu Konstrukteuren

Конструкторist eine Struktur ähnlich einer Methode, deren Zweck darin besteht, eine Instanz einer Klasse zu erstellen. Merkmale des Designers:
  • Der Name des Konstruktors muss mit dem Namen der Klasse übereinstimmen (konventionell wird der erste Buchstabe groß geschrieben, normalerweise ein Substantiv);
  • In jeder Klasse gibt es einen Konstruktor. Selbst wenn Sie keinen schreiben, erstellt der Java-Compiler einen Standardkonstruktor, der leer ist und nichts anderes tut, als den Konstruktor der Oberklasse aufzurufen.
  • Ein Konstruktor ähnelt einer Methode, ist jedoch keine Methode und wird nicht einmal als Mitglied der Klasse betrachtet. Daher kann es in einer Unterklasse nicht vererbt oder überschrieben werden.
  • Konstruktoren werden nicht vererbt;
  • In einer Klasse können mehrere Konstruktoren vorhanden sein. In diesem Fall spricht man von überladenen Konstruktoren;
  • Wenn eine Klasse keinen Konstruktor definiert, fügt der Compiler dem Code automatisch einen parameterlosen Konstruktor hinzu.
  • Ein Konstruktor hat keinen Rückgabetyp; er kann nicht einmal ein Typ sein void; wenn ein Typ zurückgegeben wird void, dann ist er trotz der Übereinstimmung mit dem Klassennamen kein Konstruktor mehr, sondern eine Methode.
  • Der Operator ist im Konstruktor erlaubt return, jedoch nur leer, ohne Rückgabewert;
  • Der Konstruktor ermöglicht die Verwendung von Zugriffsmodifikatoren; Sie können einen der Modifikatoren festlegen: public, protected, privateoder ohne Modifikator.
  • Ein Konstruktor kann nicht über die Modifikatoren abstract, final, oder ;nativestaticsynchronized
  • Das Schlüsselwort thisverweist auf einen anderen Konstruktor in derselben Klasse. Bei Verwendung muss der Aufruf in der ersten Zeile des Konstruktors erfolgen.
  • Das Schlüsselwort superruft den Konstruktor der übergeordneten Klasse auf. Bei Verwendung muss der Verweis darauf die erste Zeile des Konstruktors sein;
  • superWenn der Konstruktor den Konstruktor der Vorgängerklasse nicht aufruft (mit oder ohne Argumente), fügt der Compiler automatisch Code hinzu, um den Konstruktor der Vorgängerklasse ohne Argumente aufzurufen.

Standardkonstruktor

In jeder Klasse gibt es einen Konstruktor. Auch wenn Sie keinen schreiben, erstellt der Java-Compiler einen Standardkonstruktor. Dieser Konstruktor ist leer und ruft nur den Konstruktor der Oberklasse auf. Diese. wenn du schreibst:
public class Example {}
dann entspricht dies dem Schreiben:
public class Example
{
     Example()
     {
          super;
     }
}
In diesem Fall wird die Vorfahrenklasse nicht explizit angegeben, und standardmäßig erben alle Java-Klassen die Klasse, Objectsodass der Klassenkonstruktor aufgerufen wird Object. Wenn eine Klasse einen Konstruktor mit Parametern definiert, es aber keinen überladenen Konstruktor ohne Parameter gibt, dann ist der Aufruf des Konstruktors ohne Parameter ein Fehler. Allerdings ist es in Java seit Version 1.5 möglich, Konstruktoren mit Argumenten variabler Länge zu verwenden. Und wenn es einen Konstruktor gibt, der ein Argument variabler Länge hat, ist der Aufruf des Standardkonstruktors kein Fehler. Dies ist nicht der Fall, da das Argument mit variabler Länge leer sein kann. Das folgende Beispiel wird beispielsweise nicht kompiliert, aber wenn Sie den Konstruktor mit einem Argument variabler Länge auskommentieren, wird er erfolgreich kompiliert und ausgeführt und führt dazu, dass eine Codezeile ausgeführt wird DefaultDemo dd = new DefaultDemo(). Der Konstruktor wird aufgerufen DefaultDemo(int ... v). In diesem Fall ist es natürlich notwendig, JSDK 1.5 zu verwenden. DateiDefaultDemo.java
class DefaultDemo
{
 DefaultDemo(String s)
 {
  System.out.print("DefaultDemo(String)");
 }
 /*
 DefaultDemo(int ... v)
 {
  System.out.println("DefaultDemo(int ...)");
 }
 */

 public static void main(String args[])
 {
  DefaultDemo dd = new DefaultDemo();
 }
}
Das Ergebnis der Programmausgabe mit unkommentiertem Konstruktor:
DefaultDemo(int ...)
Im häufigen Fall jedoch, dass die Klasse überhaupt keinen Konstruktor definiert, ist der Aufruf des Standardkonstruktors (ohne Parameter) erforderlich, da die Ersetzung des Standardkonstruktors automatisch erfolgt.

Objekterstellung und Konstruktoren

Beim Erstellen eines Objekts werden die folgenden Aktionen nacheinander ausgeführt:
  • Die Objektklasse wird unter den bereits im Programm verwendeten Klassen gesucht. Ist es nicht vorhanden, wird in allen für das Programm verfügbaren Katalogen und Bibliotheken danach gesucht. Sobald eine Klasse in einem Verzeichnis oder einer Bibliothek entdeckt wird, werden die statischen Felder der Klasse erstellt und initialisiert. Diese. Für jede Klasse werden statische Felder nur einmal initialisiert.
  • Dem Objekt wird Speicher zugewiesen.
  • Die Klassenfelder werden initialisiert.
  • Der Klassenkonstruktor wird ausgeführt.
  • Es wird eine Verbindung zum erstellten und initialisierten Objekt hergestellt. Diese Referenz ist der Wert des Ausdrucks, der das Objekt erstellt. newInstance()Ein Objekt kann auch durch den Aufruf einer Klassenmethode erstellt werden java.lang.Class. In diesem Fall wird ein Konstruktor ohne Parameterliste verwendet.

Konstruktoren überladen

Konstruktoren derselben Klasse können denselben Namen und unterschiedliche Signaturen haben. Diese Eigenschaft wird Kombination oder Überladung genannt. Wenn eine Klasse über mehrere Konstruktoren verfügt, liegt eine Konstruktorüberladung vor.

Parametrisierte Konstruktoren

Die Signatur eines Konstruktors ist die Anzahl und Art der Parameter sowie die Reihenfolge ihrer Typen in der Liste der Konstruktorparameter. Der Rückgabetyp wird nicht berücksichtigt. Der Konstruktor gibt keine Parameter zurück. Diese Aussage erklärt gewissermaßen, wie Java zwischen überladenen Konstruktoren oder Methoden unterscheidet. Java unterscheidet überladene Methoden nicht nach ihrem Rückgabetyp, sondern nach der Anzahl, den Typen und der Reihenfolge der Eingabeparameter. Ein Konstruktor kann nicht einmal einen Typ zurückgeben void, sonst wird er zu einer regulären Methode, obwohl er dem Klassennamen ähnelt. Das folgende Beispiel zeigt dies. DateiVoidDemo.java
class VoidDemo
{
 /**
  * Это конструктор
  */
 VoidDemo()
 {
  System.out.println("Constructor");
 }

 /**
  * А это уже обычный метод, даже не смотря на сходство с
  * именем класса, поскольку имеется возвращаемый тип void
  */
 void VoidDemo()
 {
  System.out.println("Method");
 }

 public static void main(String s[])
 {
  VoidDemo m = new VoidDemo();
 }
}
Als Ergebnis gibt das Programm Folgendes aus:
Constructor
Dies beweist einmal mehr, dass ein Konstruktor eine Methode ohne Rückgabeparameter ist. Dem Konstruktor kann jedoch einer von drei Modifikatoren zugewiesen werden public: , privateoder protected. Und das Beispiel sieht nun so aus: DateiVoidDemo2.java
class VoidDemo2
{
 /**
  * Это конструктор
  */
 public VoidDemo2()
 {
  System.out.println("Constructor");
 }

 /**
  * А это уже обычный метод, даже не смотря на сходство с
  * именем класса, поскольку имеется возвращаемый тип void
  */
 private void VoidDemo2()
 {
  System.out.println("Method");
 }

 public static void main(String s[])
 {
  VoidDemo2 m = new VoidDemo2();
 }
}
Es ist erlaubt, einen Operator in einen Konstruktor zu schreiben return, jedoch nur einen leeren, ohne Rückgabewert. DateiReturnDemo.java
class ReturnDemo
{
 /**
  * В конструкторе допускается использование оператора
  * return без параметров.
  */
 public ReturnDemo()
 {
  System.out.println("Constructor");
  return;
 }

 public static void main(String s[])
 {
  ReturnDemo r = new ReturnDemo();
 }
}

Mit Argumenten variabler Länge parametrisierte Konstruktoren

Mit Java SDK 1.5 wurde ein lang erwartetes Tool eingeführt – Argumente variabler Länge für Konstruktoren und Methoden. Bisher wurde eine unterschiedliche Anzahl von Dokumenten auf zwei umständliche Arten verarbeitet. Die erste davon sollte sicherstellen, dass die maximale Anzahl von Argumenten auf eine kleine Anzahl beschränkt und im Voraus bekannt ist. In diesem Fall war es möglich, überladene Versionen der Methode zu erstellen, eine für jede Version der an die Methode übergebenen Liste von Argumenten. Die zweite Methode ist für etwas im Voraus Unbekanntes und eine große Anzahl von Argumenten konzipiert. In diesem Fall wurden die Argumente in einem Array platziert und dieses Array wurde an die Methode übergeben. Argumente variabler Länge sind am häufigsten bei nachfolgenden Manipulationen mit Variableninitialisierungen beteiligt. Es ist praktisch, das Fehlen einiger der erwarteten Konstruktor- oder Methodenargumente durch Standardwerte zu ersetzen. Das Argument variabler Länge ist ein Array und wird als Array behandelt. Der Konstruktor für eine Klasse mit einer variablen Anzahl von Argumenten würde beispielsweise Checkingso aussehen:
class Checking
{
 public Checking(int ... n)
 {
 }
}
Die Zeichenkombination ... teilt dem Compiler mit, dass eine variable Anzahl von Argumenten verwendet wird und dass diese Argumente in einem Array gespeichert werden, dessen Referenzwert in der Variablen n enthalten ist. Der Konstruktor kann mit einer unterschiedlichen Anzahl von Argumenten aufgerufen werden, auch ohne Argumente. Die Argumente werden automatisch in einem Array platziert und durch n geleitet. Wenn keine Argumente vorhanden sind, beträgt die Länge des Arrays 0. Die Liste der Parameter kann neben Argumenten variabler Länge auch obligatorische Parameter enthalten. In diesem Fall muss ein Parameter, der eine variable Anzahl von Argumenten enthält, der letzte in der Parameterliste sein. Zum Beispiel:
class Checking
{
 public Checking(String s, int ... n)
 {
 }
}
Eine sehr offensichtliche Einschränkung betrifft die Anzahl der Parameter variabler Länge. Die Parameterliste darf nur einen Parameter variabler Länge enthalten. Bei zwei Parametern variabler Länge ist es für den Compiler unmöglich zu bestimmen, wo ein Parameter endet und der andere beginnt. Zum Beispiel:
class Checking
{
 public Checking(String s, int ... n, double ... d) //ОШИБКА!
 {
 }
}
Datei Checking.java Es gibt beispielsweise Geräte, die Autokennzeichen erkennen und sich die Nummern der Quadrate des Bereichs merken können, den jedes der Autos tagsüber passiert hat. Aus der Gesamtmasse der registrierten Autos müssen diejenigen ausgewählt werden, die laut der Gebietskarte tagsüber zwei bestimmte Plätze besucht haben, beispielsweise 22 und 15. Es ist ganz natürlich, dass ein Auto tagsüber viele Plätze anfahren kann, oder vielleicht auch nur einen. Offensichtlich ist die Anzahl der besuchten Plätze durch die physische Geschwindigkeit des Autos begrenzt. Lassen Sie uns ein kleines Programm erstellen, in dem der Klassenkonstruktor als Argumente die Autonummer als obligatorischen Parameter und die Anzahl der besuchten Quadrate der Fläche verwendet, deren Anzahl variabel sein kann. Der Konstrukteur prüft, ob ein Auto in zwei Feldern aufgetaucht ist. Ist dies der Fall, zeigt er seine Nummer auf dem Bildschirm an.

Übergabe von Parametern an den Konstruktor

In Programmiersprachen gibt es hauptsächlich zwei Arten von Parametern:
  • Grundtypen (Primitive);
  • Verweise auf Objekte.
Der Begriff Call-by-Value bedeutet, dass der Konstruktor den ihm vom aufrufenden Modul übergebenen Wert erhält. Im Gegensatz dazu bedeutet Call by Reference, dass der Konstruktor die Adresse der Variablen vom Aufrufer erhält. Java verwendet nur Call-by-Value. Nach Parameterwert und nach Parameterverknüpfungswert. Java verwendet keine Call-by-Reference für Objekte (obwohl viele Programmierer und die Autoren einiger Bücher dies behaupten). Bei der Übergabe von Objekten an Java werden Parameter nicht als Referenz übergeben , sondern anhand des Werts der Objektreferenz ! In beiden Fällen erhält der Konstruktor Kopien der Werte aller Parameter. Der Konstruktor kann mit seinen Eingabeparametern nichts anfangen:
  • der Konstruktor kann die Werte der Eingabeparameter der Haupttypen (primitiv) nicht ändern;
  • Der Konstruktor kann Eingabeparameterverweise nicht ändern.
  • Der Konstruktor kann Eingabeparameterverweise nicht neuen Objekten zuweisen.
Der Konstruktor kann mit seinen Eingabeparametern Folgendes tun:
  • Ändern Sie den Status des als Eingabeparameter übergebenen Objekts.
Das folgende Beispiel beweist, dass in Java Eingabeparameter an einen Konstruktor als Objektreferenzwert übergeben werden. Dieses Beispiel spiegelt auch wider, dass der Konstruktor keine Referenzen von Eingabeparametern ändern kann, sondern tatsächlich Referenzen von Kopien von Eingabeparametern. DateiEmpoyee.java
class Employee
{
 Employee(String x, String y)
 {
  String temp = x;
  x = y;
  y = temp;
 }
 public static void main(String args[])
 {
  String name1 = new String("Alice");
  String name2 = new String("Mary");
  Employee a = new Employee(name1, name2);
  System.out.println("name1="+name1);
  System.out.println("name2="+name2);
 }
}
Die Ausgabe des Programms ist:
name1=Alice
name2=Mary
Wenn Java Call-by-Reference verwenden würde, um Objekte als Parameter zu übergeben, würde der Konstruktor in diesem Beispiel name1und vertauschen name2. name1Der Konstruktor tauscht die in den Variablen und gespeicherten Objektreferenzen nicht tatsächlich aus name2. Dies legt nahe, dass die Konstruktorparameter mit Kopien dieser Referenzen initialisiert werden. Dann tauscht der Konstruktor die Kopien aus. Wenn der Konstruktor seine Arbeit abschließt, werden die x- und y-Variablen zerstört und die ursprünglichen Variablen verweisen name1weiterhin name2auf die vorherigen Objekte.

Ändern der an den Konstruktor übergebenen Parameter.

Der Konstruktor kann die übergebenen Parameter von Basistypen nicht ändern. Der Konstruktor kann jedoch den Status des als Parameter übergebenen Objekts ändern. Betrachten Sie beispielsweise das folgende Programm: DateiSalary1.java
class Salary1
{
 Salary1(int x)
 {
  x = x * 3;
  System.out.println("x="+x);
 }
 public static void main(String args[])
 {
  int value = 1000;
  Salary1 s1 = new Salary1(value);
  System.out.println("value="+value);
 }
}
Die Ausgabe des Programms ist:
x=3000
value=1000
Offensichtlich wird diese Methode den Haupttypparameter nicht ändern. Daher bleibt der Wert der Variablen nach dem Aufruf des Konstruktors valuegleich 1000. Im Wesentlichen passieren drei Dinge:
  1. Die Variable xwird mit einer Kopie des Parameterwerts value(d. h. einer Zahl 1000) initialisiert.
  2. Der Wert der Variablen xwird verdreifacht – er beträgt nun 3000. Der Wert der Variablen valuebleibt jedoch gleich 1000.
  3. Der Konstruktor wird beendet und die Variable xwird nicht mehr verwendet.
Im folgenden Beispiel wird das Gehalt des Mitarbeiters erfolgreich verdreifacht, da der Wert einer Objektreferenz als Parameter an die Methode übergeben wird. DateiSalary2.java
class Salary2
{
 int value = 1000;
 Salary2()
 {
 }
 Salary2(Salary2 x)
 {
  x.value = x.value * 3;
 }
 public static void main(String args[])
 {
  Salary2 s1 = new Salary2();
  Salary2 s2 = new Salary2(s1);
  System.out.println("s1.value=" +s1.value);
  System.out.println("s2.value="+s2.value);
 }
}
Die Ausgabe des Programms ist:
s1.value=3000
s2.value=1000
Als Parameter wird der Wert der Objektreferenz verwendet. Beim Ausführen der Zeile Salary2 s2 = new Salary2(s1); Dem Konstruktor Salary2(Salary x)wird der Wert einer Referenz auf das variable Objekt übergeben s1, und der Konstruktor verdreifacht effektiv das Gehalt dafür s1.value, da sogar die (Salary x)im Konstruktor erstellte Kopie auf das variable Objekt verweist s1.

Durch Grundelemente parametrisierte Konstruktoren.

Wenn die Parameter eines überladenen Konstruktors ein Grundelement verwenden, das eingegrenzt werden kann (z. B. int <- double), ist der Aufruf einer Methode mit einem eingeengten Wert möglich, obwohl es keine mit einem solchen Parameter überladene Methode gibt. Zum Beispiel: DateiPrimitive.java
class Primitive
{
 Primitive(double d)
 {
  d = d + 10;
  System.out.println("d="+d);
 }
 public static void main(String args[])
 {
  int i = 20;
  Primitive s1 = new Primitive(i);
 }
}
Die Ausgabe des Programms ist:
d=30.0
Obwohl die Klasse Primitivekeinen Konstruktor mit einem Typparameter hat int, funktioniert ein Konstruktor mit einem Eingabeparameter double. Vor dem Aufruf des Konstruktors iwird die Variable von Typ intzu Typ erweitert double. Die umgekehrte Option, wenn die Variable ivom Typ wäre doubleund der Konstruktor nur einen Parameter hätte int, würde in dieser Situation zu einem Kompilierungsfehler führen.

Konstruktoraufruf und Operatornew

Der Konstruktor wird immer vom Operator aufgerufen new. Wenn ein Konstruktor mit dem Operator aufgerufen wird new, generiert der Konstruktor immer eine Referenz auf ein neues Objekt. Es ist unmöglich, den Konstruktor zu zwingen, einen Verweis auf ein bereits vorhandenes Objekt anstelle eines Verweises auf ein neues Objekt zu bilden, außer durch Ersetzen des zu deserialisierenden Objekts. Und mit dem neuen Operator ist es nicht möglich, anstelle einer Referenz auf ein neues Objekt eine Referenz auf ein bereits vorhandenes Objekt zu bilden. Zum Beispiel: DateiSalary3.java
class Salary3
{
 int value = 1000;
 Salary3()
 {
 }
 Salary3(Salary3 x)
 {
  x.value = x.value * 3;
 }
 public static void main(String args[])
 {
  Salary3 s1 = new Salary3();
  System.out.println("First object creation: "+s1.value);

  Salary3 s2 = new Salary3(s1);
  System.out.println("Second object creation: "+s2.value);
  System.out.println("What's happend with first object?:"+s1.value);

  Salary3 s3 = new Salary3(s1);
  System.out.println("Third object creation: "+s3.value);
  System.out.println("What's happend with first object?:"+s1.value);
 }
}
Die Ausgabe des Programms ist:
First object creation: 1000
Second object creation: 1000
What's happend with first object?: 3000
Third object creation: 1000
What's happend with first object?: 9000
Verwenden Sie zunächst die Zeile Salary3 s1 = new Salary3(); Es entsteht ein neues Objekt. Als nächstes, wenn Sie die Zeile Salary3 s2 = new Salary3(s1); verwenden oder Saiten Salary3 s3 = new Salary3(s1); Es wäre möglich, einen Link zu einem bereits vorhandenen Objekt zu erstellen, dann würden s1.value s2.valuesie s3.valuedenselben Wert speichern 1000. Eigentlich in der Zeile Salary3 s2 = new Salary3(s1); Es wird ein neues Objekt für die Variable erstellt s2und der Status des Objekts für die Variable wird geändert s1, indem der Referenzwert im Konstruktorparameter an das Objekt übergeben wird. Dies kann anhand der Ausgabeergebnisse überprüft werden. Und wenn die Zeile ausgeführt wird Salary3 s3 = new Salary3(s1); Es wird ein NEUES Objekt für die Variable erstellt s3und der Status des Objekts für die Variable ändert sich erneut s1.

Konstruktoren und Initialisierungsblöcke, Aktionsfolge beim Aufruf eines Konstruktors

Der Abschnitt Erstellen eines Objekts und Konstruktoren listet die allgemeinen Aktionen auf, die beim Erstellen eines Objekts ausgeführt werden. Dazu gehören die Prozesse der Initialisierung von Klassenfeldern und der Ausarbeitung des Klassenkonstruktors, die wiederum auch eine interne Reihenfolge haben:
  1. Alle Datenfelder werden auf ihre Standardwerte (0, false oder null) initialisiert.
  2. Alle Feldinitialisierer und Initialisierungsblöcke werden in der Reihenfolge ausgeführt, in der sie in der Klassendeklaration aufgeführt sind.
  3. Wenn in der ersten Zeile eines Konstruktors ein anderer Konstruktor aufgerufen wird, wird der aufgerufene Konstruktor ausgeführt.
  4. Der Hauptteil des Konstruktors wird ausgeführt.
Der Konstruktor hängt mit der Initialisierung zusammen, da es in Java drei Möglichkeiten gibt, ein Feld in einer Klasse zu initialisieren:
  • einen Wert in der Deklaration zuweisen;
  • Weisen Sie Werte im Initialisierungsblock zu.
  • Legen Sie seinen Wert im Konstruktor fest.
Natürlich müssen Sie den Initialisierungscode so organisieren, dass er leicht verständlich ist. Als Beispiel sei folgende Klasse genannt:
class Initialization
{
 int i;
 short z = 10;
 static int x;
 static float y;
 static
 {
  x = 2000;
  y = 3.141;
 }
 Initialization()
 {
  System.out.println("i="+i);
  System.out.println("z="+z);
  z = 20;
  System.out.println("z="+z);
 }
}
Im obigen Beispiel werden die Variablen in der folgenden Reihenfolge initialisiert: Statische Variablen werden zuerst xmit yStandardwerten initialisiert. Als nächstes wird der statische Initialisierungsblock ausgeführt. iDann wird die Variable auf den Standardwert initialisiert und die Variable initialisiert z. Als nächstes macht sich der Designer an die Arbeit. Der Aufruf von Klassenkonstruktoren sollte nicht von der Reihenfolge abhängen, in der Felder deklariert werden. Dies kann zu Fehlern führen.

Konstruktoren und Vererbung

Konstruktoren werden nicht vererbt. Zum Beispiel:
public class Example
{
 Example()
 {
 }
 public void sayHi()
 {
  system.out.println("Hi");
 }
}

public class SubClass extends Example
{
}
Die Klasse SubClasserbt automatisch die sayHi()in der übergeordneten Klasse definierte Methode. Gleichzeitig Example()wird der Konstruktor der übergeordneten Klasse nicht von ihrem Nachkommen geerbt SubClass.

Schlüsselwort thisin Konstruktoren

Konstruktoren werden verwendet this, um auf einen anderen Konstruktor in derselben Klasse zu verweisen, jedoch mit einer anderen Parameterliste. Wenn der Konstruktor das Schlüsselwort verwendet this, muss es in der ersten Zeile stehen; das Ignorieren dieser Regel führt zu einem Compilerfehler. Zum Beispiel: DateiThisDemo.java
public class ThisDemo
{
 String name;
 ThisDemo(String s)
 {
  name = s;
     System.out.println(name);
 }
 ThisDemo()
 {
  this("John");
 }
 public static void main(String args[])
 {
  ThisDemo td1 = new ThisDemo("Mary");
  ThisDemo td2 = new ThisDemo();
 }
}
Die Ausgabe des Programms ist:
Mary
John
In diesem Beispiel gibt es zwei Konstruktoren. Der erste erhält ein String-Argument. Der zweite erhält keine Argumente, sondern ruft einfach den ersten Konstruktor mit dem Standardnamen „John“ auf. Somit können Sie Konstruktoren verwenden, um Feldwerte explizit und standardmäßig zu initialisieren, was in Programmen oft notwendig ist.

Schlüsselwort superin Konstruktoren

Konstruktoren werden verwendet super, um einen Superklassenkonstruktor aufzurufen. Wenn der Konstruktor verwendet super, muss dieser Aufruf in der ersten Zeile erfolgen, andernfalls gibt der Compiler einen Fehler aus. Unten finden Sie ein Beispiel: DateiSuperClassDemo.java
public class SuperClassDemo
{
 SuperClassDemo()
 {
 }
}

class Child extends SuperClassDemo
{
 Child()
 {
  super();
 }
}
In diesem einfachen Beispiel Child()enthält der Konstruktor einen Aufruf , der zusätzlich zur super()Klasse eine Instanz der Klasse erstellt . Da es sich um die erste Anweisung handeln muss, die in einem Unterklassenkonstruktor ausgeführt wird, ist diese Reihenfolge immer gleich und hängt nicht davon ab, ob . Wenn es nicht verwendet wird, wird zuerst der Standardkonstruktor (ohne Parameter) jeder Oberklasse, beginnend mit der Basisklasse, ausgeführt. Das folgende Programm demonstriert, wann Konstruktoren ausgeführt werden. DateiSuperClassDemoChildsupersuper()Call.java
//Создать суперкласс A
class A
{
 A()
 {
  System.out.println("Inside A constructor.");
 }
}

//Создать подкласс B, расширяющий класс A
class B extends A
{
 B()
 {
  System.out.println("Inside B constructor.");
 }
}

//Создать класс (C), расширяющий класс В
class C extends B
{
 C()
 {
  System.out.println("Inside C constructor.");
 }
}

class Call
{
 public static void main(String args[])
 {
  C c = new C();
 }
}
Ausgabe dieses Programms:
Inside A constructor.
Inside B constructor.
Inside C constructor.
Konstruktoren werden in der Reihenfolge ihrer Klassenunterordnung aufgerufen. Das macht durchaus Sinn. Da die Oberklasse keine Unterklasse kennt, ist jede Initialisierung, die sie durchführen muss, separat. Wenn möglich, sollte es vor jeder von der Unterklasse durchgeführten Initialisierung erfolgen. Deshalb sollte es zuerst getan werden.

Anpassbare Konstruktoren

Der Laufzeittypidentifizierungsmechanismus ist eines der leistungsstarken Kernprinzipien der Java-Sprache, die Polymorphismus implementiert. Allerdings schützt ein solcher Mechanismus den Entwickler in manchen Fällen nicht vor inkompatibler Typumwandlung. Der häufigste Fall ist die Manipulation einer Gruppe von Objekten, deren verschiedene Typen im Voraus unbekannt sind und zur Laufzeit bestimmt werden. Da Fehler im Zusammenhang mit Typinkompatibilität nur zur Laufzeit auftreten können, ist es schwierig, sie zu finden und zu beheben. Die Einführung benutzerdefinierter Typen in Java 2 5.0 verlagert einige dieser Fehler von der Laufzeit zur Kompilierungszeit und bietet einen Teil der fehlenden Typsicherheit. ObjectBeim Übergang von einem Typ zu einem konkreten Typ ist keine explizite Typumwandlung erforderlich . Es ist zu beachten, dass Typanpassungstools nur mit Objekten funktionieren und nicht auf primitive Datentypen anwendbar sind, die außerhalb des Klassenvererbungsbaums liegen. Bei benutzerdefinierten Typen werden alle Umwandlungen automatisch und im Hintergrund durchgeführt. Dadurch können Sie sich vor Typkonflikten schützen und Code viel häufiger wiederverwenden. Benutzerdefinierte Typen können in Konstruktoren verwendet werden. Konstruktoren können benutzerdefiniert sein, auch wenn ihre Klasse kein benutzerdefinierter Typ ist. Zum Beispiel:
class GenConstructor
{
 private double val;
 <T extends Number> GenConstructor(T arg)
 {
   val = arg.doubleValue();
 }

 void printValue()
 {
  System.out.println("val: "+val);
 }
}

class GenConstructorDemo
{
 public static void main(String args[])
 {
  GenConstructor gc1 = new GenConstructor(100);
  GenConstructor gc2 = new GenConstructor(123.5F);

  gc1.printValue();
  gc2.printValue();
 }
}
Da der Konstruktor GenConstructoreinen benutzerdefinierten Typparameter angibt, der eine von class abgeleitete Klasse sein muss Number, kann er von jedem aufgerufen werden
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION