Warum wird eine statische Methode als Methode betrachtet?

135

Ich schreibe eine Erklärung für einen Code für einen Kurs und habe die Wörter versehentlich methodund functionaustauschbar verwendet. Ich beschloss, noch einmal hinüberzugehen und den Wortlaut zu korrigieren, stieß aber auf ein Loch in meinem Verständnis.

Soweit ich functionweiß , ist eine Unterroutine eine, wenn sie nicht auf eine Instanz einer Klasse einwirkt (ihre Wirkung ist auf ihre explizite Eingabe / Ausgabe beschränkt), und eine, methodwenn sie auf eine Instanz einer Klasse angewendet wird (sie kann übertragen werden) Nebenwirkungen auf die Instanz, die sie unrein machen).

Hier gibt es eine gute Diskussion zu diesem Thema. Beachten Sie, dass nach den Definitionen der akzeptierten Antwort eine Statik methodtatsächlich eine Funktion sein sollte, da eine Instanz niemals implizit übergeben wird und keinen Zugriff auf die Mitglieder einer Instanz hat.

Sollte Static nicht methodstatsächlich Funktionen sein?

Nach ihrer Definition handeln sie nicht auf bestimmte Instanzen einer Klasse. Sie sind nur aufgrund ihrer Beziehung an die Klasse "gebunden". Ich habe einige gut aussehende Websites gesehen, die statische Unterprogramme als "Methoden" bezeichnen ( Oracle , Fredosaurus , ProgrammingSimplified ). Entweder übersehen sie alle die Terminologie, oder ich vermisse etwas (meine Vermutung ist die letztere). .

Ich möchte sicherstellen, dass ich den richtigen Wortlaut verwende.
Kann jemand das klären?

Carcigenicate
quelle
2
Ich dachte immer, es sei Funktion in PHP und Methode in Java. Grundsätzlich das gleiche mit verschiedenen Namen
JK
19
Es gibt einen Unterschied zwischen theoretischer Informatik und der Art und Weise, wie eine Sprache sie anwendet. Das JLS macht keinen Unterschied und nennt es eine Methode.
Jeroen Vannevel
2
Es könnte an den Definitionen der Begriffe „Funktion“ und „Methode“ in Python zu sehen von Interesse sein, wo es ist ein Unterschied: im Grunde eine Funktion ist ein Stück Code , mit einer Symboltabelle und einer Aufrufkonvention, während ein Verfahren , was Sie erhalten, wenn Sie eine Funktion in eine Klasse einfügen. Der Unterschied ist jedoch ziemlich subtil, selbst für Leute, die Python kennen.
David Z
2
Als ich Theorie lernte, lernte ich, dass Funktion einen Wert zurückgibt und Prozedur nicht. Dann lernte ich, wie Java Funktionen und Prozeduren aufruft. Jetzt versuche ich funktionale Programmierung und eine Funktion ist idempotent. Die Begriffe ändern ihre Bedeutung im Kontext.
Emory

Antworten:

123

Dieses Zitat aus 8.4.3.2 kann helfen:

Eine deklarierte Methode staticwird als Klassenmethode bezeichnet .

Eine nicht deklarierte Methode staticwird als Instanzmethode [...] bezeichnet.

  • Klassenmethoden: einer Klasse zugeordnet.
  • Instanzmethoden: einer Instanz zugeordnet.

Java möchte nur, dass Sie "objektorientiert denken". Statische Methoden haben auch Zugriff auf einen umgebenden Bereich, der den Status enthalten kann. In gewisser Weise ist die Klasse wie ein Objekt selbst.

Radiodef
quelle
Obwohl "Funktion" als Ausführungseinheit in Java technisch korrekt ist, ist die bevorzugte Nomenklatur in fast ganz Java "Methode", da alle Java-Funktionen Teil einer Klasse oder Schnittstelle sind (ausgenommen Lambdas und möglicherweise einige andere Dinge, die mir nicht bewusst sind).
Schrotflinte Ninja
1
Lambdas sind eigentlich anonyme innere Klassen mit der @FunctionalInterfaceAnnotation und mit 1 Methode unter der Haube. Ein Lambda ist nur syntaktischer Zucker und in dieser Hinsicht gibt es nichts Neues.
Adam Arold
1
@AdamArold Lambdas sind ein bisschen schicker als eine anonyme innere Klasse. Beispielsweise können nicht erfassende Lambdas eine Instanz für mehrere Auswertungen eines bestimmten Ausdrucks gemeinsam nutzen. (Aber Sie haben Recht, sie werden letztendlich zu statischen und Instanzmethoden kompiliert.)
Radiodef
@Radiodef Vielleicht wäre eine bessere Formulierung: "Alle Lambda-Ausdrücke können durch äquivalente Nicht-Lambda-Ausdrücke ersetzt werden, ohne dass Änderungen an anderen Dateien als denjenigen vorgenommen werden, die den Lambda-Ausdruck enthalten" oder ähnliches.
user253751
4
Das ist mir peinlich. Ich komme aus Scala und habe es trotzdem geschafft, die Tatsache zu übersehen, dass die Klasse selbst objektartig ist. Danke dir.
Carcigenicate
80

Die einfache Antwort lautet: Als Java beschloss, alles als "Methode" zu bezeichnen, kümmerte es sie nicht um die Unterscheidung zwischen einer Funktion und einer Methode in der theoretischen Informatik.

Bitcoin M.
quelle
3
Das stimmt. Bis einschließlich Java 7 finden Sie nicht einmal das Wort "Funktion" in der Sprachspezifikation
Erwin Bolwidt
4
So sehr mir die Einfachheit dieser Antwort gefällt, denke ich, dass die Antwort von Radiodef eher auf dem richtigen Weg ist, da sie den entscheidenden Punkt erwähnt, dass die Klasse selbst als Objekt fungiert. Trotzdem danke.
Carcigenicate
2
Interessanterweise geht dies mit den Entscheidungen früherer Sprachen einher, nicht zwischen Funktionen und Unterprogrammen zu unterscheiden.
Random832
4
Ich bin unangenehm überrascht, dass diese Antwort so viele positive Stimmen erhalten hat. Erstens gibt diese Antwort vor, dass es keine Klassenmethoden gibt. Zweitens ist dies kaum ein in Java eingeführtes Konzept. Klassenmethoden gab es zum Beispiel bereits in Smalltalk, das es Jahrzehnte gab, bevor Java zu einer Sache wurde.
Malcolm
1
@ Malcolm Ich muss dir zustimmen. Nach Prüfung der anderen Antworten scheint dies falsch zu sein. Es ist keine Apathie seitens des Java-Erstellers, es sei denn, es war ihnen wirklich egal, aber sie haben es trotzdem richtig benannt.
Carcigenicate
26

Statische Methoden sind nicht genau Funktionen, der Unterschied ist subtil, aber wichtig.

Eine statische Methode, bei der nur bestimmte Eingabeparameter verwendet werden, ist im Wesentlichen eine Funktion.

Statische Methoden können jedoch auf statische Variablen und andere statische Funktionen zugreifen (auch unter Verwendung statischer Variablen), sodass statische Methoden einen Zustand haben können, der sich grundlegend von einer Funktion unterscheidet, die per Definition zustandslos ist . (ADDENDUM: Während Programmierer mit der Verwendung von "Funktion" als Definition oft nicht so streng umgehen, kann eine strenge Funktion in der Informatik nur auf Eingabeparameter zugreifen.) Wenn Sie diesen Fall des Zugriffs auf statische Felder definieren, ist es nicht gültig zu sagen, dass statische Methoden immer Funktionen sind.

Ein weiterer Unterschied, der die Verwendung der "statischen Methode" rechtfertigt, besteht darin, dass Sie in C abgeleitete globale Funktionen und globale Variablen definieren können, auf die überall zugegriffen werden kann. Wenn Sie nicht auf die Klasse zugreifen können, die statische Methoden enthält, können Sie auch nicht auf die Methoden zugreifen. Daher sind "statische Methoden" im Gegensatz zu globalen Funktionen in ihrem Umfang konstruktionsbedingt begrenzt.

Thorsten S.
quelle
2
Diese Antwort gefällt mir irgendwie, aber ich möchte einige Dinge besser verstehen. Ist das nicht eher eine "reine" vs "nebenwirksame" Funktion als eine Funktion vs Methode? Oder ist es so, dass eine Methode aufgrund von Nebenwirkungen so ist? Ich mache hier nur ein Brainstorming.
Nadir Sampaoli
2
Diese Antwort ist richtig. Man könnte jedoch argumentieren, dass Funktionen in vielen (den meisten?) Sprachen auf globale Variablen zugreifen können, so dass sie oft nicht streng zustandslos sind (gleiche Eingabe, gleiche Ausgabe). Und im Fall von statischen Java-Methoden kann der Zugriff auf Klassenvariablen als äquivalent zum Zugriff auf "globale" (dh nicht lokal für eine Funktion / Methode) Variablen angesehen werden - wobei die Klasseninstanz eine Art Namespace ist.
Leonbloy
1
@leonbloy Pure Funktionale Programmiersprachen wie Haskell sind völlig zustandslos. Es gibt nichts, was als globale Variable bezeichnet werden kann.
Thorsten S.
17

In Java ist eine benutzerdefinierte Klasse tatsächlich eine Instanz einer Unterklasse von java.lang.Class.

In diesem Sinne statische Methoden sind auf eine Instanz einer konzeptuellen Klasse angehängt: sie zu einer Instanz einer Unterklasse von java.lang.Class angebracht ist.

In diesem Sinne beginnt der Begriff "Klassenmethode" (ein alternativer Name für die statischen Methoden von Java) Sinn zu machen. Und der Begriff "Klassenmethode" ist an vielen Stellen zu finden: Ziel C, Smalltalk und JLS - um nur einige zu nennen.

Mike Clark
quelle
Ist es möglich, zwei Instanzen dieser Unterklasse zu haben?
Random832
Natürlich können Sie eine Klasse in verschiedene Klassenladeprogramme laden (der Grund für das Abrufen von ClassCastExceptions mit der Meldung "CustomClass kann nicht in CustomClass umgewandelt werden").
Dunni
2
@ Random832 - irgendwie. Sie können zwei (oder mehr) Instanzen derselben Klassenunterklasse in derselben JVM haben, sofern jede Instanz über einen eigenen Klassenladeprogramm verfügt. Sie können dieselbe Klassenunterklasse nicht mehr als einmal pro Klassenladeprogramm instanziieren. Es wird ein wenig verwirrend und Analogien zu klassischen OO-Konzepten werden an dieser Stelle etwas dünner.
Mike Clark
@ MikeClark Wenn ich das mache, sind sie wirklich gleich? Wird die Klassenunterklasse dieselbe Klasse sein, auch wenn die Klasse selbst eine andere Instanz davon ist? Klassenlader sind für mich ziemlich verwirrend. Könnte ich (ohne Reflexion) eine statische Methode der Instanz eines Klassenladeprogramms einer Klasse aus der Instanz eines anderen Klassenladeprogramms derselben Klasse aufrufen, indem ein Verweis darauf übergeben wird? Was ist, wenn sie unterschiedliche Methoden haben?
Random832
1
@ Random832 "Irgendwie?" Sind aus rein OO-theoretischer Sicht zwei Instanzen einer Klasse jemals wirklich genau gleich? Mindestens zwei ansonsten identische Instanzen derselben Klasse haben unterschiedliche Adressen. Wie können wir sonst zwei Dinge haben? Das einzige, was genau dasselbe ist wie etwas, ist das Ding selbst.
Mike Clark
11

In der Informatik ist die Funktion eindeutig einer statischen Methode zugeordnet. Aber "Methode" einer Klasse ist ein bisschen generisch, wie "Mitglied" (Feldmitglied, Methodenmitglied). Es gibt Formulierungen wie

Datenelemente und Methodenelemente haben zwei separate Namensräume: .x und .x () können nebeneinander existieren.

Der Grund ist also, dass Sprache, wie der Philosoph Ludwig Wittgenstein sagte, ein Werkzeug mit unterschiedlichen Kontexten ist. "Methode" ist ein netter Spitzname im obigen Zitat, um ein "Mitglied" zu kategorisieren.

Joop Eggen
quelle
9

Dein Denken ist richtig und es macht Sinn. Es ist einfach keine etablierte Terminologie in der Java-Community. Lassen Sie mich einige Interna erklären, die helfen können, zu verstehen, warum die Terminologie existiert.

Java ist eine klassenbasierte objektorientierte Sprache. Eine Methode ist immer Mitglied einer Klasse oder Instanz (Dies ist eine allgemeine Anweisung, die auch für andere Programmiersprachen gültig ist). Wir denken, dass Klasse und Instanz beide Objekte sind.

Instanzmethode (dynamisch)

Sie können diese Methode nicht direkt von einer Klasse aus aufrufen, sondern müssen eine Instanz erstellen. Jede Instanz verweist auf diese Methode. Sie können eine Methodendefinition mit genau derselben Methodensignatur (bei Unterklassen) überschreiben, dh die Referenz verweist auf eine andere Methode (die dieselbe Signatur hat, aber einen anderen Methodenkörper haben kann). Die Methode ist dynamisch.

Klassenmethode (statisch)

Sie können diese Methode nur direkt von der Klasse aus aufrufen, dh Sie müssen keine Instanz dieser Klasse erstellen. Es gibt nur eine globale Definition dieser Methode im gesamten Programm. Sie können nicht genau dieselbe Methodensignatur überschreiben, wenn die Methode als statisch deklariert ist, da nur eine Definition für das gesamte Programm gültig ist. Beachten Sie, dass die Methode Mitglied des Klassenobjekts selbst ist. Die Instanzen haben alle denselben eindeutigen (und festen) Verweis auf diese Methode.

Ely
quelle
7

Hier ist eine weitere Interpretation der Terminologie, bei der Scala als Mnemonik verwendet wird:
In Scala haben Sieobject s, die Singleton-Instanzen einer implizit definierten Klasse sind1 .

Gemäß Ihrer Definition können wir diese Unterroutinen aufrufen, die zu gehören object Methoden , da sie auf einer einzelnen Instanz der Klasse ausgeführt werden.
Zusätzlich definiert das Objekt auch Klasse A und erstellt alle Methoden in Objekt A als statische Methoden in Klasse A (für die Schnittstelle mit Java) [2] .

Daher können wir sagen, dass die statischen Methoden der Java-Klasse A auf dieselben Mitglieder wie die Scala-Singleton-Instanz zugreifen, die gemäß Ihrer Definition den Namen (statisch) verdienen. Methoden der Klasse A bezeichnet werden sollten.

mucaho
quelle
Toller Vergleich. Ich kenne Scala, daher ist Ihre objectReferenz sehr sinnvoll. Danke dir.
Carcigenicate
2

Der Hauptunterschied besteht natürlich darin, dass die Methode statische Felder verwenden kann, nicht nur Methodenparameter. Aber es gibt noch einen - Polymorphismus! Ergebnisse der Bewertung Die Klassen A.doTheSameStaticMethod () und ClassB.doTheSameStaticMehod () hängen von der Klasse ab. In diesem Fall ist die Funktion machtlos.

Павел Бивойно
quelle
1

Jede Klasse verfügt über ein Objekt, das eine Instanz einer Unterklasse der ClassKlasse darstellt. Statische Methoden sind wirklich Instanzmethoden für diese Objekte, die Instanzen einer Unterklasse der Klasse sind. Sie haben Zugriff auf den Status in Form von statischen Feldern, sodass sie nicht nur (zustandslose) Funktionen sind. Sie sind Methoden.

Böhmisch
quelle