class Employee{
String name;
int id;
//No explicit constructors
}
Jetzt kann ich folgende Aussage aufrufen:
Employee e1 = new Employee();
Mit dem obigen Code liefert der Compiler die Definition für den Konstruktor Employee()
.
Wenn ich einen einzelnen expliziten Konstruktor wie folgt definiere:
class Employee{
String name;
int id;
Employee(String aName){
this.name=aName;
}
}
Warum kann ich die folgende Aussage nicht aufrufen:
Employee e2 = new Employee();
Obwohl der Compiler weiß, wie man eine Definition von bereitstellt Employee()
.
Employee(String aName)
Warum kann ich keinen Standardkonstruktor verwenden , nur weil ich einen expliziten Konstruktor definiert habe ?
Wenn der Compiler die Verwendung des Standardkonstruktors auch nach der Definition eines expliziten Konstruktors zugelassen hätte, hätte dies uns geholfen, den Code für den Standardkonstruktor wiederzuverwenden.
java
class
constructors
Harish_N
quelle
quelle
Antworten:
Zunächst wird kein Standardkonstruktor generiert, der vom Compiler bereitgestellt wird, wenn der Konstruktor ohne Argumente nicht explizit geschrieben wird.
Wenn Sie keinen Konstruktor ohne Argumente explizit für eine Klasse schreiben, beschwert sich der Compiler nicht, solange Objekte ohne Parameterkonstruktoren erstellt werden (da der Compiler dem Standardkonstruktor das Erstellen von Objekten ermöglicht, wodurch selbst der Konstruktor ohne Argumente aufgerufen wird ).
Wenn Sie jedoch einen Konstruktor ohne Argumente definieren, prüft der Compiler beim Kompilieren den Aufruf des Konstruktors und seine Definition in der Klasse. Es ist so, als würde man eine andere Methode einer Klasse authentifizieren.
Es wird also ein Fehler ausgegeben, wenn Sie nach dem Definieren eines parametrisierten Konstruktors einen Konstruktor ohne Argumente aufrufen, da kein Konstruktor ohne Argumente explizit in der Klasse definiert ist. Dies ist logisch korrekt, da dies eine gute Möglichkeit ist, wenn Sie die Erstellung von Objekten ohne Daten blockieren möchten.
Angenommen, einem Mitarbeiterobjekt muss eine Mitarbeiter-ID zugeordnet sein. Definieren Sie dazu einen einzelnen Argumentkonstruktor und keinen Konstruktor ohne Argumente.
quelle
Ein Konstruktor mit Argumenten ist nicht nur eine praktische Abkürzung für die Verwendung von Setzern. Sie schreiben einen Konstruktor, um sicherzustellen, dass ein Objekt niemals existiert, ohne dass bestimmte Daten vorhanden sind.
Wenn es keine solche Anforderung gibt, gut. Wenn es jedoch einen gibt, wie aus der Tatsache hervorgeht, dass Sie einen solchen Konstruktor geschrieben haben, ist es unverantwortlich, einen Standardkonstruktor zu generieren, mit dem ein Client die Regel "Kein Objekt ohne Daten" umgehen kann. Doppelt so, weil der automatisch generierte Standardkonstruktor für einen zufälligen Codeleser unsichtbar ist , was die Tatsache verbirgt, dass er existiert! Nein, wenn Sie Konstruktoren mit Argumenten und einem Standardkonstruktor möchten , müssen Sie den Standardkonstruktor selbst schreiben. Es ist sowieso nicht so, als wäre es ein großer Aufwand, einen leeren Block zu schreiben.
quelle
Java, das einen parameterlosen Konstruktor generiert, wenn Sie keinen anderen haben, ist wie ein höflicher Kellner, der Ihren Mantel für Sie nimmt.
Java, das nach dem Definieren einer anderen Version immer noch einen parameterlosen Konstruktor generiert, ist wie derselbe Kellner, der Ihnen den Mantel auszieht, nachdem Sie klar angegeben haben, dass Sie Ihre eigenen Pläne haben, was Sie mit dem Mantel tun sollen.
Wenn ich eine Klasse habe (die ich unveränderlich sein möchte):
Und ich füge einen Konstruktor hinzu:
Und Java sollte immer noch einen standardmäßigen, parameterlosen Konstruktor bereitstellen, dann kann dieser Code nicht kompiliert werden, da
firstName
undlastName
Felder als endgültig deklariert werden, aber nach dem Aufruf nicht festgelegt werdenPerson p = new Person()
.Sie zwingen mich, eine weitere Implementierung bereitzustellen:
Und da ich es nicht will - da es nutzlos ist, könnte ich geneigt sein, Totenkopf darauf zu legen:
Aber ich kann einem anderen Entwickler immer noch nicht verbieten, eine Methode zu erstellen (innerhalb der
Person
Klasse hat es also nicht geholfen, den Konstruktor als privat zu markieren):All diese Aufregung könnte - und wird - vermieden werden, da Java (und nicht nur Java) so funktioniert, wie es funktioniert.
Wenn Sie eine Methode definieren
setCoordinates(int x, int y)
, erwarten Sie nicht, dass der Compiler automatisch eine parameterlose Version davon akzeptiertsetCoordinates()
. Es würde nichts tun.Wie unterscheidet sich dies von der Erwartung eines parameterlosen Konstruktors? Nun, offensichtlich macht ein Konstruktor immer mindestens eine Sache - er erstellt ein Objekt (oder stirbt beim Versuch).
Aber ich möchte die Kontrolle darüber haben, wie meine Objekte instanziiert werden sollen. Wenn ich gezwungen werde, einen parameterlosen Konstruktor zu haben, egal was ich tue, wird mir diese Kontrolle genommen.
quelle
Die Sprache gibt Ihnen den Standardkonstruktor als Gefallen. Die Vermutung ist, dass, wenn Sie einen benutzerdefinierten Konstruktor geschrieben haben, Ihr Konstruktor ohne Argumente möglicherweise auch besondere Aufmerksamkeit erfordert. Kein guter Grund, aber auch nicht schrecklich.
Der sekundäre Grund ist, dass Cruft sich nur auf diese Sprache stapelt, ohne an ihre Symmetrie mit der bestehenden Praxis zu denken und sehr wenig Interesse daran zu haben, sie lesbar zu machen. Stoustroups ursprüngliches "C with Classes" war ein gehackter C-Präprozessor, der es wahrscheinlich nicht aus dem Labor schaffen sollte. Die Welt ist so lustig.
quelle
Wenn Sie einen Konstruktor mit einem Parameter definieren, muss dies einen gültigen Grund haben. Möglicherweise ist dieser Parameter für Ihre Klasse so wichtig, dass der Objektstatus ohne ihn ungültig ist. Aus diesem Grund erstellt Java keinen Konstruktor ohne Argumente für Sie, wenn Sie bereits einen definieren.
Wenn Sie der Meinung sind, dass es praktisch wäre, einen Konstruktor ohne Argumente zu haben, können Sie ihn trotzdem definieren:
quelle