9 Stimmen

Was ist das Äquivalent zu virtuellen Funktionen von C++ in PHP?

Ist es abstrakte Funktion xxx?

Ich habe gerade einen Test gemacht, der darauf hinweist, dass eine private Methode auch dann virtual sein sollte?

Klasse a {
 private function test()
 {
  echo 1;
 }
}

Klasse b erweitert a {
 private function test()
 {
  echo 2;
 }
 public function aufruf()
 {
  $this->test();
 }
}

$instanz = new b;
$instanz->aufruf();

Die Ausgabe lautet 2

18voto

Yacoby Punkte 52756

In PHP sind alle nicht privaten Funktionen virtuell, daher ist es nicht notwendig, sie explizit als virtuell zu deklarieren.

Das Deklarieren einer Memberfunktion als abstract bedeutet einfach, dass die Basisklasse keine Implementierung bereitstellen kann, aber alle abgeleiteten Klassen sollten. Die Definition der Methode als abstrakt ist dasselbe wie das folgende in C++

virtual void foo() = 0;

Das bedeutet einfach, dass abgeleitete Klassen müssen foo(); implementieren.

EDIT: In Bezug auf die bearbeitete Frage

b::call() kann nicht auf a::test() zugreifen. Aus diesem Grund wird beim Aufrufen privater Funktionen nur die in der Klasse aufgerufene Funktion aufgerufen.

EDIT: In Bezug auf den Kommentar:

(Von Wikipieda)

In der objektorientierten Programmierung ist eine virtuelle Funktion oder Methode eine Funktion oder Methode, deren Verhalten in einer ableitenden Klasse von einer Funktion mit derselben Signatur überschrieben werden kann.

Aufgrund der Idee, in C++ explizit anzugeben, wofür man bezahlt, müssen Funktionen als virtuell deklariert werden, um abgeleiteten Klassen das Überschreiben einer Funktion zu ermöglichen.

class Foo{
public:
    void baz(){
        std::cout << "Foo";
    }
};
class Bar : public Foo{
public:
    void baz(){
        std::cout << "Bar";
    }
};

int main(){
    Foo* f = new Bar();
    f->baz(); //baz ist in Foo nicht virtual, daher lautet die Ausgabe Foo
}

Ändern Sie baz, damit es virtual ist

class Foo{
public:
    virtual void baz(){
        std::cout << "Foo";
    }
};
//Gleiche Bar-Deklaration

int main(){
    Foo* f = new Bar();
    f->baz(); //baz ist in Foo virtual, daher lautet die Ausgabe Bar, da die abgeleitete Funktion aufgerufen wird
}

Beachten Sie, wenn die Variable f im obigen Beispiel vom Typ Bar* oder Bar wäre, wäre es egal, ob Foo::baz() virtual ist oder nicht, da der beabsichtigte Typ bekannt ist (Der Programmierer hat ihn explizit angegeben)

4voto

Michael Will Punkte 41

Das Beispiel zeigte kein typisches Spezialisierungsmuster, bei dem b keine Implementierungsdetails von call() kennen muss, sondern angeben kann, wie test() ausgeführt werden soll. Leider gibt es 1 zurück. Durch Deklarieren der Funktion als protected anstelle von private funktioniert es jedoch wie erwartet.

class a {
    protected function test()
    {
        echo 1;
    }
    public function call() {
        $this->test();
    }
}

class b extends a {
    protected function test()
    {
      echo 2;
    }
}

$instance = new b();
$instance->call();

2voto

KOLANICH Punkte 2543

Verwenden Sie das Schlüsselwort static (php 5.4) nicht $this->meth() sondern static::meth()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X