Warum können Konstruktoren in Java nicht endgültig, statisch oder abstrakt sein?
Können Sie mir zum Beispiel erklären, warum dies nicht gültig ist?
public class K {
abstract public K() {
// ...
}
}
Wenn Sie eine Methode als final
festlegen, bedeutet dies: "Ich möchte nicht, dass eine Klasse sie überschreibt." Aber gemäß der Java-Sprachspezifikation:
JLS 8.8 - "Konstruktordeklarationen sind keine Mitglieder. Sie werden niemals vererbt und unterliegen daher keinem Verstecken oder Überschreiben."
Wenn Sie eine Methode als abstract
festlegen, bedeutet dies: "Diese Methode hat keinen Körper und sollte in einer untergeordneten Klasse implementiert werden." Der Konstruktor wird jedoch implizit aufgerufen, wenn das Schlüsselwort new
verwendet wird, sodass ihm kein Rumpf fehlen kann.
Wenn Sie eine Methode als static
festlegen, bedeutet dies: "Diese Methode gehört zur Klasse, nicht zu einem bestimmten Objekt." Da der Konstruktor jedoch implizit aufgerufen wird, um ein Objekt zu initialisieren, gibt es keinen Zweck, einen statischen Konstruktor zu haben.
Die Frage ist eigentlich, warum Konstruktor static or abstract or final
sein soll.
Konstruktoren werden nicht vererbt. Sie können daher nicht überschrieben werden. endgültigen Konstruktor haben
Der Konstruktor wird automatisch aufgerufen, wenn eine Instanz der Klasse .__ ist. erstellt, hat es Zugriff auf Instanzfelder der Klasse. Was sein wird die Verwendung eines statischen Konstruktors.
Konstruktor kann nicht überschrieben werden. Was machen Sie also mit einer abstrakten Konstrukteur.
Ein Java-Konstruktor ist implizit final, die statischen/nicht-statischen Aspekte seiner Semantik sind implizit 1und es ist bedeutungslos , dass ein Java-Konstruktor abstrakt ist.
Dies bedeutet, dass die Modifizierer final
und static
redundant sind und das Schlüsselwort abstract
überhaupt keine Bedeutung hat.
Natürlich sahen die Java-Designer keinen Sinn darin, redundante und/oder bedeutungslose Zugriffsmodifizierer für Konstruktoren zuzulassen. Diese sind also in der Java-Grammatik nicht zulässig.
Nebenbei: Es ist eine Schande, dass sie nicht denselben Designaufruf für Schnittstellenmethoden gemacht haben, bei denen die Modifizierer public
und abstract
ebenfalls redundant sind, jedoch trotzdem zulässig sind. Vielleicht gibt es dafür einen (alten) historischen Grund. Auf jeden Fall kann es nicht behoben werden, ohne dass (wahrscheinlich) Millionen vorhandener Java-Programme nicht kompiliert werden können.
1 - Konstruktoren haben eigentlich eine Mischung aus statischer und nicht statischer Semantik. Sie können keinen Konstruktor für eine Instanz "aufrufen", und sie werden nicht vererbt oder überschrieben. Dies ist ähnlich wie bei statischen Methoden. Andererseits kann der Rumpf eines Konstruktors auf this
verweisen und Instanzmethoden aufrufen ... wie eine Instanzmethode. Und dann gibt es eine Konstruktorkette, die nur für Konstruktoren gilt. Der eigentliche Punkt ist jedoch, dass diese Semantik fest ist und es keinen Sinn macht, einen redundanten und möglicherweise verwirrenden static
-Modifikator zuzulassen.
public
constructor : Objekte können überall erstellt werden.
Standardkonstruktor : Objekte können nur in demselben Paket erstellt werden.
protected
constructor : Objekte können von Klassen außerhalb des Pakets nur erstellt werden, wenn es sich um eine Unterklasse handelt.
private
constructor : Objekt kann nur innerhalb der Klasse erstellt werden (z. B. beim Implementieren eines Singleton).
Die Schlüsselwörter static
, final
und abstract
sind für einen Konstruktor nicht von Bedeutung, weil:
static
Mitglieder gehören zu einer Klasse, der Konstruktor wird jedoch benötigt, um ein Objekt zu erstellen.
Eine abstract
-Klasse ist eine teilweise implementierte Klasse, die abstrakte Methoden enthält, die in der Kindklasse implementiert werden sollen.
final
beschränkt die Änderung: Variablen werden konstant, Methoden können nicht überschrieben werden und Klassen können nicht vererbt werden.
Kein Konstruktor kann NIEMALS als final deklariert werden. Ihr Compiler gibt immer einen Fehler vom Typ "Modifier final nicht erlaubt" Final bedeutet, wenn es auf Methoden angewendet wird, dass die Methode in einer Unterklasse nicht überschrieben werden kann. Konstruktoren sind keine gewöhnlichen Methoden. (es gelten andere Regeln) .__ Außerdem werden Konstruktoren NIE vererbt. Es gibt also keinen Sinn, es als endgültig zu erklären.
Final : Weil Sie einen Konstruktor sowieso nicht überschreiben/erweitern können. Sie können eine Klasse erweitern (um zu verhindern, dass Sie sie als final definieren) oder eine Methode überschreiben (um zu verhindern, dass Sie sie als final deklarieren), aber für Konstruktoren gibt es nichts dergleichen.
Static : Wenn Sie die Ausführung eines Konstruktors betrachten, ist er nicht statisch (er kann auf Instanzfelder zugreifen). Wenn Sie sich die Anruferseite ansehen, ist dies (irgendwie) statisch (Sie rufen es ohne Instanz auf. Es ist schwer.) Um sich einen Konstruktor als vollständig statisch oder nicht statisch vorzustellen und ohne eine semantische Trennung zwischen diesen beiden Dingen zu haben, ist es nicht sinnvoll, sie mit einem Modifikator zu unterscheiden.
Abstract : Abstract macht nur bei Vorhandensein von Überschreiben/Erweiterung Sinn, daher gilt das gleiche Argument wie für 'final'
JLS Abschnitt 8 erwähnt dies.
Konstruktoren (§8.8) sind Methoden ähnlich, können jedoch nicht aufgerufen werden direkt durch einen Methodenaufruf; Sie werden verwendet, um die neue Klasse zu initialisieren Instanzen. Sie können wie Methoden überladen sein (§8.8.8).
Konstruktoren sind jedoch keine regulären Methoden. Sie können nicht als solche verglichen werden.
warum Konstruktor nicht statisch und endgültig sein kann, ist in den obigen Antworten gut definiert.
Abstract: "Abstract" bedeutet keine Implementierung. und es kann nur durch Vererbung implementiert werden. Wenn wir also eine Klasse erweitern, werden alle übergeordneten Klassenmitglieder in der Unterklasse (untergeordnete Klasse) mit Ausnahme von "Konstruktor" geerbt. Nehmen wir also an, Sie schaffen es, den Konstruktor als "abstrakt" zu deklarieren, und wie können Sie die Implementierung in einer Unterklasse angeben, wenn der Konstruktor nicht in der Kindklasse erbt?
deshalb kann der Konstruktor nicht abstrakt sein.
sehen wir zuerstfinal public K () {
* über dem Modifikator final ist einschränkend, weil dann, wenn es final ist, eine Situation auftritt, in der wir es nur in einer anderen Klasse oder in derselben Klasse überschreiben, so dass dies hier nicht in der Nähe nicht final geschieht.
we want public void(int i,String name){
//this code not allowed
lassen Sie static, statisch itz alles über die Klassenebene, aber wir erstellen den objektbasierten Konstruktor mit dem 'new'-Schlüsselwort also , thatsall
am schlimmsten ist es hier nicht, weil es keine abstrakte oder deklarierte Methode gibt