Die Frage ist in Java, warum ich keine abstrakte statische Methode definieren kann. zum Beispiel
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
java
abstract-class
static-methods
hhafez
quelle
quelle
Antworten:
Denn "abstrakt" bedeutet: "Implementiert keine Funktionalität" und "statisch" bedeutet: "Es gibt Funktionalität, auch wenn Sie keine Objektinstanz haben". Und das ist ein logischer Widerspruch.
quelle
abstract static
wäre, wäre das vollkommen sinnvoll. Es wäre eine Methode des Klassenobjekts selbst, die Unterklassenobjekte implementieren müssen. Natürlich ist die Art und Weise, wie Ihre Antwort steht, richtig, obwohl ich mich mit der Sprache befasst habe.abstract static
: Eine Funktion X, die "in der Unterklasse implementiert" ist, kann nicht gleichzeitig "in der Klasse ausgeführt" werden - nur in der Unterklasse . Wo es dann nicht mehr abstrakt ist.static
bedeutet nicht "nicht leer" - das ist nur eine Folge von Java, das nicht zulässt, dass statische Methoden abstrakt sind. Es bedeutet "aufrufbar für die Klasse". (Es sollte " nur für die Klasse aufrufbar" bedeuten, aber das ist ein anderes Problem.) Wenn Javaabstract static
Methoden unterstützt , würde ich erwarten, dass die Methode 1) von Unterklassen implementiert werden muss und 2) eine Klassenmethode der Unterklasse ist. Einige Methoden sind als Instanzmethoden einfach nicht sinnvoll. Leider können Sie dies in Java beim Erstellen einer abstrakten Basisklasse (oder einer Schnittstelle) nicht angeben.Schlechtes Sprachdesign. Es wäre viel effektiver, eine statische abstrakte Methode direkt aufzurufen, als eine Instanz nur für die Verwendung dieser abstrakten Methode zu erstellen. Dies gilt insbesondere dann, wenn eine abstrakte Klasse als Problemumgehung für die Enum-Unfähigkeit zum Erweitern verwendet wird. Dies ist ein weiteres schlechtes Designbeispiel. Ich hoffe, sie lösen diese Einschränkungen in einer nächsten Version.
quelle
static
selbst bereits eine Verletzung ist ....Sie können eine statische Methode nicht überschreiben, daher wäre es bedeutungslos, sie abstrakt zu machen. Darüber hinaus würde eine statische Methode in einer abstrakten Klasse zu dieser Klasse gehören und nicht zur übergeordneten Klasse, sodass sie ohnehin nicht verwendet werden kann.
quelle
Die
abstract
Anmerkung zu einer Methode gibt an, dass die Methode in einer Unterklasse überschrieben werden muss.In Java kann ein
static
Mitglied (Methode oder Feld) nicht durch Unterklassen überschrieben werden (dies gilt nicht unbedingt für andere objektorientierte Sprachen, siehe SmallTalk). Einstatic
Mitglied kann ausgeblendet sein , dies unterscheidet sich jedoch grundlegend von dem überschriebenen .Da statische Elemente in einer Unterklasse nicht überschrieben werden können, kann die
abstract
Anmerkung nicht auf sie angewendet werden.Abgesehen davon unterstützen andere Sprachen die statische Vererbung, genau wie die Instanzvererbung. Aus syntaktischer Sicht erfordern diese Sprachen normalerweise, dass der Klassenname in der Anweisung enthalten ist. In Java sind dies beispielsweise unter der Annahme, dass Sie Code in ClassA schreiben, äquivalente Anweisungen (wenn methodA () eine statische Methode ist und es keine Instanzmethode mit derselben Signatur gibt):
und
In SmallTalk ist der Klassenname nicht optional, daher lautet die Syntax (beachten Sie, dass SmallTalk das. Nicht verwendet, um das "Subjekt" und das "Verb" zu trennen, sondern es stattdessen als Abschlusszeichen für statemend verwendet):
Da der Klassenname immer erforderlich ist, kann die richtige "Version" der Methode immer durch Durchlaufen der Klassenhierarchie ermittelt werden. Für das, was es wert ist, vermisse ich gelegentlich die
static
Vererbung und wurde von dem Mangel an statischer Vererbung in Java gebissen, als ich damit anfing. Darüber hinaus ist SmallTalk vom Typ Ente (und unterstützt daher kein vertragliches Programm). Daher gibt es keinenabstract
Modifikator für Klassenmitglieder.quelle
Ich habe auch die gleiche Frage gestellt, hier ist warum
Da die Abstract-Klasse sagt, wird sie keine Implementierung geben und es der Unterklasse erlauben, sie zu geben
Die Unterklasse muss also die Methoden der Oberklasse überschreiben.
REGEL NR. 1 - Eine statische Methode kann nicht überschrieben werden
Da statische Elemente und Methoden Elemente zur Kompilierungszeit sind, ist das Überladen (Polymorphismus der Kompilierungszeit) statischer Methoden eher zulässig als das Überschreiben (Laufzeitpolymorphismus).
Sie können also nicht abstrakt sein.
Es gibt nichts wie abstrakte statische <--- In Java Universe nicht erlaubt
quelle
abstract static
siehe stackoverflow.com/questions/370962/... . Der wahre Grund, warum Java das Überschreiben statischer Methoden nicht zulässt, liegt darin, dass Java das Überschreiben statischer Methoden nicht zulässt.foo(String)
ist es nicht dasselbe wiefoo(Integer)
- das ist alles was es ist.Dies ist ein schreckliches Sprachdesign und wirklich kein Grund, warum es nicht möglich sein kann.
In der Tat, hier ist eine Implementierung, wie es CAN in getan werden , JAVA :
================= Altes Beispiel unten =================
Suchen Sie nach getRequest, und getRequestImpl ... setInstance kann aufgerufen werden, um die Implementierung zu ändern, bevor der Aufruf erfolgt.
Wird wie folgt verwendet:
quelle
abstract static
Methode angegeben haben, wie sie in der Frage gestellt wurde, und Sie haben in Fettdruck geschrieben, KANN IN JAVA GEMACHT WERDEN . Das ist völlig falsch.Eine abstrakte Methode ist nur so definiert, dass sie in einer Unterklasse überschrieben werden kann. Statische Methoden können jedoch nicht überschrieben werden. Daher ist es ein Fehler bei der Kompilierung, eine abstrakte, statische Methode zu haben.
Nun ist die nächste Frage, warum statische Methoden nicht überschrieben werden können?
Dies liegt daran, dass statische Methoden zu einer bestimmten Klasse und nicht zu ihrer Instanz gehören. Wenn Sie versuchen, eine statische Methode zu überschreiben, wird kein Kompilierungs- oder Laufzeitfehler angezeigt, aber der Compiler würde nur die statische Methode der Oberklasse ausblenden.
quelle
Eine statische Methode muss per Definition nicht wissen
this
. Daher kann es sich nicht um eine virtuelle Methode handeln (die gemäß den über verfügbaren dynamischen Unterklasseninformationen überladen istthis
). Stattdessen basiert eine statische Methodenüberladung ausschließlich auf Informationen, die zum Zeitpunkt der Kompilierung verfügbar sind (dies bedeutet: Wenn Sie eine statische Methode der Oberklasse referenzieren, rufen Sie nämlich die Oberklassenmethode auf, jedoch niemals eine Unterklassenmethode).Demnach wären abstrakte statische Methoden völlig nutzlos, da die Referenz niemals durch einen definierten Körper ersetzt wird.
quelle
Ich sehe, dass es bereits unzählige Antworten gibt, aber ich sehe keine praktischen Lösungen. Dies ist natürlich ein echtes Problem und es gibt keinen guten Grund, diese Syntax in Java auszuschließen. Da der ursprünglichen Frage ein Kontext fehlt, in dem dies erforderlich sein könnte, biete ich sowohl einen Kontext als auch eine Lösung an:
Angenommen, Sie haben eine statische Methode in einer Reihe von Klassen, die identisch sind. Diese Methoden rufen eine statische Methode auf, die klassenspezifisch ist:
doWork()
Methoden inC1
undC2
sind identisch. Möglicherweise gibt es viele dieser Probleme:C3
C4
usw. Wenn diesstatic abstract
zulässig wäre, würden Sie den doppelten Code entfernen , indem Sie Folgendes tun:Dies würde jedoch nicht kompiliert, da eine
static abstract
Kombination nicht zulässig ist. Dies kann jedoch mit einemstatic class
Konstrukt umgangen werden , das erlaubt ist:Mit dieser Lösung wird nur Code dupliziert
quelle
C1.doWork()
oderC2.doWork()
Sie können jedoch nicht anrufenC.doWork()
. Nehmen wir auch in dem von Ihnen bereitgestellten Beispiel an, was nicht funktioniert. Angenommen, wenn dies zulässig war, wie findet die Klasse dannC
die Implementierung vondoMoreWork()
? Schließlich würde ich Ihren Kontextcode als schlechtes Design bezeichnen. Warum? einfach, weil Sie eine separate Funktion für den Code erstellt haben, die eindeutig ist, anstatt eine Funktion für den gemeinsamen Code zu erstellen und dann eine statische Funktion in der Klasse zu implementierenC
. Das ist einfacher !!!Angenommen, es gibt zwei Klassen
Parent
undChild
.Parent
istabstract
. Die Erklärungen lauten wie folgt:Dies bedeutet, dass jede Instanz von
Parent
angeben muss, wie sierun()
ausgeführt wird.Nehmen wir jetzt jedoch an, dass dies
Parent
nicht der Fall istabstract
.Dies bedeutet,
Parent.run()
dass die statische Methode ausgeführt wird.Die Definition einer
abstract
Methode lautet "Eine Methode, die deklariert, aber nicht implementiert ist", was bedeutet, dass sie selbst nichts zurückgibt.Die Definition einer
static
Methode lautet "Eine Methode, die unabhängig von der Instanz, auf der sie aufgerufen wird, denselben Wert für dieselben Parameter zurückgibt".abstract
Der Rückgabewert einer Methode ändert sich, wenn sich die Instanz ändert. Einestatic
Methode wird nicht. Einestatic abstract
Methode ist so ziemlich eine Methode, bei der der Rückgabewert konstant ist, aber nichts zurückgibt. Dies ist ein logischer Widerspruch.Es gibt auch wirklich keinen Grund für eine
static abstract
Methode.quelle
Eine abstrakte Klasse kann keine statische Methode haben, da eine Abstraktion durchgeführt wird, um eine DYNAMISCHE BINDUNG zu erreichen, während statische Methoden statisch an ihre Funktionalität gebunden sind. Eine statische Methode bedeutet, dass das Verhalten nicht von einer Instanzvariablen abhängig ist, sodass keine Instanz / kein Objekt erforderlich ist. Nur die Klasse. Statische Methoden gehören zur Klasse und nicht zum Objekt. Sie werden in einem als PERMGEN bekannten Speicherbereich gespeichert, von wo aus sie mit jedem Objekt gemeinsam genutzt werden. Methoden in abstrakten Klassen werden dynamisch an ihre Funktionalität gebunden.
quelle
Deklarieren eine Methode als
static
Mittel , die wir diese Methode von seinen Klassennamen aufrufen können und wenn diese Klasse istabstract
auch, macht es keinen Sinn , es zu nennen , da es keinen Körper enthält, und daher können wir keine Methode deklarieren sowohl alsstatic
undabstract
.quelle
Da abstrakte Methoden zur Klasse gehören und von der implementierenden Klasse nicht überschrieben werden können. Auch wenn es eine statische Methode mit derselben Signatur gibt, wird die Methode ausgeblendet und nicht überschrieben. Daher ist es unerheblich, die abstrakte Methode als statisch zu deklarieren, da sie niemals den Körper erhält. Daher Fehler beim Kompilieren.
quelle
Eine statische Methode kann ohne eine Instanz der Klasse aufgerufen werden. In Ihrem Beispiel können Sie foo.bar2 () aufrufen, nicht jedoch foo.bar (), da Sie für bar eine Instanz benötigen. Der folgende Code würde funktionieren:
Wenn Sie eine statische Methode aufrufen, wird immer derselbe Code ausgeführt. Selbst wenn Sie im obigen Beispiel bar2 in ImplementsFoo neu definieren, würde ein Aufruf von var.bar2 () foo.bar2 () ausführen.
Wenn bar2 jetzt keine Implementierung hat (was abstrakt bedeutet), können Sie eine Methode ohne Implementierung aufrufen. Das ist sehr schädlich.
quelle
Ich glaube, ich habe die Antwort auf diese Frage in der Form gefunden, warum die Methoden einer Schnittstelle (die wie abstrakte Methoden in einer übergeordneten Klasse funktionieren) nicht statisch sein können. Hier ist die vollständige Antwort (nicht meine)
Grundsätzlich können statische Methoden zur Kompilierungszeit gebunden werden, da Sie zum Aufrufen eine Klasse angeben müssen. Dies unterscheidet sich von Instanzmethoden, für die die Klasse der Referenz, von der aus Sie die Methode aufrufen, zur Kompilierungszeit möglicherweise unbekannt ist (daher kann der aufgerufene Codeblock nur zur Laufzeit bestimmt werden).
Wenn Sie eine statische Methode aufrufen, kennen Sie bereits die Klasse, in der sie implementiert ist, oder direkte Unterklassen davon. Wenn Sie definieren
Dann ist jeder
Foo.bar();
Anruf offensichtlich illegal und wird immer verwendetFoo2.bar();
.Vor diesem Hintergrund besteht der einzige Zweck einer statischen abstrakten Methode darin, Unterklassen zur Implementierung einer solchen Methode zu erzwingen. Sie könnten zunächst denken, dass dies SEHR falsch ist, aber wenn Sie einen generischen Typparameter
<E extends MySuperClass>
haben, wäre es schön, dies über eine Schnittstelle zu garantieren, die diesE
kann.doSomething()
. Beachten Sie, dass Generika aufgrund von Typlöschungen nur zur Kompilierungszeit vorhanden sind.Wäre es also nützlich? Ja, und vielleicht erlaubt Java 8 deshalb statische Methoden in Schnittstellen (allerdings nur mit einer Standardimplementierung). Warum nicht abstrakte statische Methoden mit einer Standardimplementierung in Klassen? Einfach, weil eine abstrakte Methode mit einer Standardimplementierung tatsächlich eine konkrete Methode ist.
Warum nicht abstrakte / Schnittstellen-statische Methoden ohne Standardimplementierung? Anscheinend nur aufgrund der Art und Weise, wie Java identifiziert, welchen Codeblock es ausführen muss (erster Teil meiner Antwort).
quelle
Da die abstrakte Klasse ein OOPS-Konzept ist und statische Elemente nicht Teil von OOPS sind ...
Jetzt können wir statische vollständige Methoden in der Schnittstelle deklarieren und die Schnittstelle ausführen, indem wir die Hauptmethode innerhalb einer Schnittstelle deklarieren
quelle
Die Idee einer abstrakten statischen Methode wäre, dass Sie diese bestimmte abstrakte Klasse nicht direkt für diese Methode verwenden können, sondern nur die erste Ableitung diese statische Methode implementieren darf (oder für Generika: die tatsächliche Klasse des generischen Sie verwenden).
Auf diese Weise können Sie beispielsweise eine abstrakte Klasse sortableObject oder sogar eine Schnittstelle mit (automatisch) abstrakten statischen Methoden erstellen, die die Parameter der Sortieroptionen definiert:
Jetzt können Sie ein sortierbares Objekt definieren, das nach den Haupttypen sortiert werden kann, die für alle diese Objekte gleich sind:
Jetzt können Sie eine erstellen
Das kann die Typen abrufen, ein Popup-Menü erstellen, um einen Typ zum Sortieren auszuwählen und die Liste neu abzurufen, indem die Daten von diesem Typ abgerufen werden, sowie eine Add-Funktion haben, die, wenn ein Sortiertyp ausgewählt wurde, automatisch ausgeführt werden kann -sortieren Sie neue Elemente in. Beachten Sie, dass die Instanz von SortableList direkt auf die statische Methode von "T" zugreifen kann:
Das Problem bei der Verwendung einer Instanz besteht darin, dass die SortableList möglicherweise noch keine Elemente enthält, aber bereits die bevorzugte Sortierung bereitstellen muss.
Cheerio, Olaf.
quelle
Erstens ein wichtiger Punkt zu abstrakten Klassen - Eine abstrakte Klasse kann nicht instanziiert werden (siehe Wiki ). Sie können also keine Instanz einer abstrakten Klasse erstellen .
Die Art und Weise, wie Java mit statischen Methoden umgeht, besteht darin, die Methode für alle Instanzen dieser Klasse freizugeben.
Wenn Sie eine Klasse nicht instanziieren können, kann diese Klasse keine abstrakten statischen Methoden haben, da eine abstrakte Methode erweitert werden muss.
Boom.
quelle
Gemäß Java- Dokument :
In Java 8 sind neben Standardmethoden auch statische Methoden in einer Schnittstelle zulässig. Dies erleichtert uns die Organisation von Hilfsmethoden in unseren Bibliotheken. Wir können statische Methoden, die für eine Schnittstelle spezifisch sind, in derselben Schnittstelle und nicht in einer separaten Klasse aufbewahren.
Ein schönes Beispiel dafür ist:
anstatt
Ein weiteres Beispiel für die Verwendung statischer Methoden finden Sie auch in doc selbst:
quelle
Weil 'abstrakt' bedeutet, dass die Methode überschrieben werden soll und man 'statische' Methoden nicht überschreiben kann.
quelle
Reguläre Methoden können abstrakt sein, wenn sie von Unterklassen überschrieben und mit Funktionen versehen werden sollen. Stellen Sie sich vor, die Klasse
Foo
wird umBar1, Bar2, Bar3
usw. erweitert . Jede hat also ihre eigene Version der abstrakten Klasse, je nach ihren Bedürfnissen.Jetzt gehören statische Methoden per Definition zur Klasse, sie haben nichts mit den Objekten der Klasse oder den Objekten ihrer Unterklassen zu tun. Sie brauchen sie nicht einmal zu existieren, sie können verwendet werden, ohne die Klassen zu instanziieren. Daher müssen sie einsatzbereit sein und können sich nicht auf die Unterklassen verlassen, um ihnen Funktionen hinzuzufügen.
quelle
Da abstract ein Schlüsselwort ist, das auf Abstract-Methoden angewendet wird, geben Sie keinen Body an. Und wenn wir über statisches Schlüsselwort sprechen, gehört es zum Klassenbereich.
quelle
Wenn Sie ein statisches Element oder eine statische Variable in der Klasse verwenden, wird diese beim Laden der Klasse geladen.
quelle
Sie können dies mit Schnittstellen in Java 8 tun.
Dies ist die offizielle Dokumentation dazu:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
quelle
Denn wenn eine Klasse eine abstrakte Klasse erweitert, muss sie abstrakte Methoden überschreiben, und das ist obligatorisch. Und da statische Methoden Klassenmethoden sind, die zur Kompilierungszeit aufgelöst werden, während überschriebene Methoden Instanzmethoden sind, die zur Laufzeit und nach dynamischem Polymorphismus aufgelöst werden.
quelle