it-swarm.com.de

Warum können statische Methoden nicht statische Methoden nicht direkt aufrufen?

Ich verstehe nicht, warum die meisten Programmiersprachen Entwicklern/Benutzern nicht erlauben, nicht statische Methoden direkt von statischen Methoden aufzurufen. Was ist der Grund dafür?

p.s. Ich weiß, Sie können ein Objekt erstellen und eine nicht statische Methode aus einer statischen Methode aufrufen.

4
Abhishek

Weil ein statisches Feld/eine statische Methode per Definition nicht an ein einzelnes Objekt/eine einzelne Instanz der Klasse gebunden ist, während sich ein nicht statisches Feld/eine nicht statische Methode immer auf ein tatsächliches Objekt/eine tatsächliche Instanz bezieht.

Da dies wahrscheinlich zu vage/abstrakt klang, um die Frage zu beantworten, und diese Art von Verwirrung normalerweise auf einem Missverständnis darüber beruht, was Statik tatsächlich bedeutet, lassen Sie uns dies mit einem C++ - ähnlichen Pseudocode konkretisieren:

class Foo {
public:
    static int a() { return 2; }
    int b()        { return d_x; }
    Foo(int x)     { d_x = x; }
private:
    int d_x;
}

Die statische Methode a ist nicht an eine bestimmte Instanz von Foo gebunden, dh sie kann von überall aufgerufen werden, unabhängig davon, ob Sie ein tatsächliches Foo -Objekt haben oder nicht. In C++ würden Sie einfach Foo::a() schreiben und es würde immer 2 zurückgeben.

Die nicht statische Methode b ist an eine einzelne Instanz von Foo gebunden. Da das int einfach in einem bestimmten Foo -Objekt zurückgegeben wird, ist es nicht sinnvoll, b() ohne ein bestimmtes Foo -Objekt aufzurufen. Was würden Sie erwarten, wenn es zurückkehren würde, wenn es kein Foo hätte? Foo f; f.b(); macht also Sinn, Foo::b() jedoch nicht.

Wenn ich versucht habe, a() b () aufzurufen, dann immer, wenn ich a() ohne eine tatsächliche Instanz von Foo aufgerufen habe, Ich würde auch b() ohne eine tatsächliche Instanz von Foo aufrufen, also macht jetzt a() auch keinen Sinn .

Im Wesentlichen sind die beiden Methoden ungefähr so ​​implementiert:

namespace Foo {
    int a() {
        return 2;
    }
    int b(Foo* this) {
        return this->x;
    }
};

Wenn Sie die Methoden so betrachten, ist es ziemlich offensichtlich, warum b() a()] aufrufen kann, aber nicht umgekehrt: a() hat einfach keinen Foo* herumliegen, um b () zu geben.


Übrigens können Sie diese Einschränkung "umgehen", indem Sie eine statische Methode schreiben, die ein tatsächliches Foo -Objekt verwendet und dann nicht statisch aufruft Methoden für dieses Foo Objekt. Aber das ist normalerweise ein Codegeruch, der anzeigt, dass Sie statische Methoden haben, die nicht statisch oder nicht statisch sein sollten, die statisch sein sollten, oder eine Klasse, die versucht, zu viele Dinge gleichzeitig zu tun.

14
Ixrec

Etwas ironisch ... Oder zumindest ist dies die funktionale Perspektive auf Methoden ...

Es gibt keine "Methode"

class Apple
{
 ...
public void Eat()
{
    this.weight --;
}
public static Apple ChangeColor(Apple apple)
{
    Apple.color = Color.GetRandomColor();
}
} 

Das obige Beispiel definiert eine Klasse mit zwei Methoden, eine statische und eine nicht. Die zweite ist eigentlich eine Funktion , die einen einzelnen Parameter vom Typ Apple Typ) empfängt und seine Farbe ändert. Die erste ist auch eine Funktion , die implizit einen Parameter namens this empfängt und verringert sein Gewicht.

Das ist im Grunde die Idee hinter einer 'Mitgliedsfunktion'/'Mitgliedsmethode'. Es empfängt einen impliziten ersten Parameter vom Typ der Klasse.

gehen Sie dazu folgendermaßen vor: Apple.Eat() macht keinen Sinn, es gibt zu wenige Parameter (Apple ist hier der Klassenname).

während dies tut:

Apple x = new Apple();
x.eat()

Dieser 'implizite erste Parameter' von 'Mitgliedsmethoden' in OOP Sprachen hat auch eine Besonderheit. Wenn eine Mitgliedsmethode virtuell (sprachspezifisch) ist, lautet die Methode dynamisch aufgerufen basierend auf dem Typ dieses Parameters.

Dynamischer Versand oder dynamischer Aufruf ähnelt Methodenüberladungen - das entscheidet, welche Methode basierend auf dem Typ der Kompilierungszeit aufgerufen werden soll, außer dass dies zur Laufzeit geschieht .

Einige Programmiersprachen erlauben dies für alle Parameter einer Funktion - dies wird als Mehrfachversand bezeichnet

Obwohl die meisten OOP - Sprachen dies nur für den 'ersten impliziten Parameter' von 'Mitgliedsmethoden' zulassen - dies wird als virtuelle Methoden, Polymorphismus und Einzelversand bezeichnet.


Übrigens ... Es gibt ein ganzes Entwurfsmuster namens Besucher , um nur eine Art Mehrfachversand an Sprachen zu ermöglichen, die diese Funktion nicht haben

1
AK_

Weil alle statischen Dinge nicht mit einem Objekt zusammenhängen, sondern mit einer Klasse. Alle Objekte derselben Klasse greifen also auf dieselben statischen Methoden zu.

Andererseits werden nicht statische Methoden an ein bestimmtes Objekt einer Klasse angehängt.

Sie können statische Methoden aufrufen, ohne ein Objekt einer Klasse zu erstellen. Dies ist jedoch bei nicht statischen Methoden nicht der Fall.

0
Mahesh Shah