PHP objektorientiert

Objektorientiert (kurz OO) ist eine Programmieridee und Methodik, die die Daten in einem Programm zusammen mit den Methoden, die auf den Daten operieren, kapselt und so „Objekte“ bildet, und die Funktionen des Programms durch Interaktion und Nachrichtenaustausch zwischen Objekten erfüllt. Objektorientierte Programmierung betont Merkmale wie Kapselung, Vererbung, Polymorphismus und dynamische Bindung, wodurch das Programm erweiterbarer, wartbarer und wiederverwendbarer wird.

In der objektorientierten Programmierung (englisch: Object-oriented programming, abgekürzt OOP) ist ein Objekt ein Ganzes, das aus Informationen und der Beschreibung der Verarbeitung dieser Informationen besteht, und es ist eine Abstraktion der realen Welt.

In der realen Welt ist alles, dem wir begegnen, ein Objekt, wie Computer, Fernseher, Fahrräder und so weiter.

Die drei Hauptmerkmale eines Objekts:

  • Objektverhalten: die Operationen, die ein Objekt ausführen kann. Zum Beispiel sind das Einschalten oder Ausschalten eines Lichts Verhaltensweisen.
  • Objektform: wie das Objekt auf verschiedene Verhaltensweisen reagiert, z. B. Farbe, Größe und Aussehen.
  • Objektdarstellung: Die Darstellung eines Objekts entspricht einem Ausweis und unterscheidet gezielt die Unterschiede zwischen Objekten mit demselben Verhalten und Zustand.

Zum Beispiel ist Animal eine abstrakte Klasse. Wir können sie als Hund und Schaf festlegen. Hund und Schaf sind konkrete Objekte. Sie haben Farbattribute und Verhaltenszustände wie Bellen und Laufen.

Drei Hauptmerkmale der objektorientierten Programmierung:

  • Kapselung: bezieht sich auf das Zusammenfassen der Eigenschaften und Methoden eines Objekts, sodass von außen nicht direkt auf den internen Zustand des Objekts zugegriffen oder dieser geändert werden kann. Durch die Verwendung von Zugriffssteuerungsmodifikatoren (public, private, protected) zur Einschränkung des Zugriffs auf Eigenschaften und Methoden wird die Kapselung erreicht.

  • Vererbung: bezieht sich auf die Fähigkeit, eine neue Klasse zu erstellen, die die Eigenschaften und Methoden einer Elternklasse erbt und eigene Eigenschaften und Methoden hinzufügen kann. Durch Vererbung können Sie vermeiden, ähnlichen Code wiederholt zu schreiben, und Code-Wiederverwendung erreichen.

  • Polymorphismus: bezieht sich auf die Fähigkeit, eine Variable vom Typ einer Elternklasse zu verwenden, um auf Objekte verschiedener Unterklassentypen zu verweisen, wodurch einheitliche Operationen auf verschiedene Objekte erreicht werden. Polymorphismus macht den Code flexibler, mit besserer Erweiterbarkeit und Wartbarkeit. In PHP kann Polymorphismus durch die Implementierung von Schnittstellen und die Verwendung abstrakter Klassen erreicht werden.


Objektorientierter Inhalt

  • Klasse− Definiert die abstrakten Merkmale einer Sache. Die Definition einer Klasse umfasst die Form der Daten und die Operationen auf den Daten.

  • Objekt− Ist eine Instanz einer Klasse.

  • Membervariablen− Variablen, die innerhalb einer Klasse definiert sind. Der Wert der Variablen ist von außen nicht sichtbar, aber über Memberfunktionen kann darauf zugegriffen werden. Nachdem die Klasse als Objekt instanziiert wurde, wird die Variable zu einer Eigenschaft des Objekts.

  • Memberfunktionen− Innerhalb der Klasse definiert, können sie verwendet werden, um auf die Daten des Objekts zuzugreifen.

  • Vererbung− Vererbung ist ein Mechanismus, durch den eine Unterklasse automatisch die Datenstrukturen und Methoden der Elternklasse gemeinsam nutzt; sie ist eine Beziehung zwischen Klassen. Beim Definieren und Implementieren einer Klasse können Sie auf der Grundlage einer bestehenden Klasse aufbauen, die von der bestehenden Klasse definierten Inhalte als eigene übernehmen und einige neue Inhalte hinzufügen.

  • Elternklasse− Wenn eine Klasse von anderen Klassen geerbt wird, kann diese Klasse als Elternklasse, Basisklasse oder Oberklasse bezeichnet werden.

  • Kindklasse− Eine Klasse, die von einer anderen Klasse erbt, wird als Kindklasse bezeichnet, auch bekannt als abgeleitete Klasse.

  • Polymorphismus− Polymorphismus bedeutet, dass dieselbe Funktion oder Methode auf mehrere Objekttypen wirken und unterschiedliche Ergebnisse liefern kann. Verschiedene Objekte, die dieselbe Nachricht empfangen, können unterschiedliche Ergebnisse erzeugen; dieses Phänomen nennt man Polymorphismus.

  • Überladen− Einfach ausgedrückt ist es die Situation, in der Funktionen oder Methoden denselben Namen, aber unterschiedliche Parameterlisten haben. Solche Funktionen oder Methoden mit demselben Namen, aber unterschiedlichen Parametern werden überladene Funktionen oder Methoden genannt.

  • Abstraktion− Abstraktion bedeutet, Objekte mit konsistenten Datenstrukturen (Attributen) und Verhaltensweisen (Operationen) zu Klassen zu abstrahieren. Eine Klasse ist eine solche Abstraktion; sie spiegelt wichtige Eigenschaften im Zusammenhang mit der Anwendung wider, während sie andere irrelevante Inhalte ignoriert. Jede Klassifikation von Klassen ist subjektiv, muss aber mit der konkreten Anwendung zusammenhängen.

  • Kapselung− Kapselung bedeutet, die Attribute und Verhaltensweisen eines in der realen Welt existierenden Objekts zusammenzubinden und sie in einer logischen Einheit unterzubringen.

  • Konstruktor− Wird hauptsächlich dazu verwendet, ein Objekt beim Erstellen zu initialisieren, das heißt, den Mitgliedsvariablen des Objekts Anfangswerte zuzuweisen. Er wird immer zusammen mit dem new-Operator in Anweisungen verwendet, die Objekte erstellen.

  • Destruktor− Der Destruktor ist das Gegenteil des Konstruktors. Wenn ein Objekt seinen Lebenszyklus beendet (zum Beispiel, wenn die Funktion, die das Objekt enthält, ihre Ausführung beendet hat), führt das System automatisch den Destruktor aus. Der Destruktor wird oft verwendet, um "Aufräumarbeiten" durchzuführen (zum Beispiel, wenn beim Erstellen des Objekts mit new Speicherplatz belegt wurde, sollte dieser vor dem Verlassen mit delete im Destruktor freigegeben werden).

In der folgenden Abbildung haben wir mit der Klasse Car drei Objekte erstellt: Mercedes, Bmw und Audi.

$mercedes = new Car ();
$bmw = new Car ();
$audi = new Car ();


PHP-Klassendefinition

Die übliche Syntax zum Definieren einer Klasse in PHP lautet wie folgt:

<?php
class phpClass {
  var $var1;
  var $var2 = "constant string";
  
  function myfunc ($arg1, $arg2) {
     [..]
  }
  [..]
}
?>

Die Analyse sieht wie folgt aus:

  • Klassen werden unter Verwendung vonclass, dem Schlüsselwort class, gefolgt vom Klassennamen definiert.

  • Variablen und Methoden können innerhalb des Paares geschweifter Klammern ({}) nach dem Klassennamen definiert werden.

  • Klassenvariablen werden mitvardeklariert, und Variablen können auch mit Werten initialisiert werden.

  • Funktionsdefinitionen ähneln PHP-Funktionsdefinitionen, aber auf Funktionen kann nur über die Klasse und ihre instanziierten Objekte zugegriffen werden.

Beispiel

<?php
class Site {
  /* 成员变量 */
  var $url;
  var $title;
  
  /* 成员函数 */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
?>

Die Variable$this$this repräsentiert das Objekt selbst.

PHP_EOList das Zeilenumbruchzeichen.


Erstellen von Objekten in PHP

Nachdem eine Klasse erstellt wurde, können wir dennew-Operator verwenden, um ein Objekt der Klasse zu instanziieren:

$example = new Site;
$taobao = new Site;
$google = new Site;

Im obigen Code haben wir drei Objekte erstellt. Jedes der drei Objekte ist unabhängig. Als Nächstes sehen wir uns an, wie man auf Member-Methoden und Member-Variablen zugreift.

Aufrufen von Member-Methoden

Nach dem Instanziieren eines Objekts können wir das Objekt verwenden, um Member-Methoden aufzurufen. Die Member-Methoden des Objekts können nur auf die Member-Variablen des Objekts zugreifen:

// 调用成员函数,设置标题和URL
$example->setTitle( "Example" );
$taobao->setTitle( "淘宝" );
$google->setTitle( "Google 搜索" );

$example->setUrl( 'www.example.com' );
$taobao->setUrl( 'www.taobao.com' );
$google->setUrl( 'www.google.com' );

// 调用成员函数,获取标题和URL
$example->getTitle();
$taobao->getTitle();
$google->getTitle();

$example->getUrl();
$taobao->getUrl();
$google->getUrl();

Der vollständige Code sieht wie folgt aus:

Beispiel

<?php
class Site {
  
/* Membervariablen */
  
var $url;
  var
$title;
  
  
/* Memberfunktionen */
  
function setUrl($par){
    
$this->url = $par;
  }
  
  function
getUrl(){
     echo
$this->url . PHP_EOL;
  }
  
  function
setTitle($par){
    
$this->title = $par;
  }
  
  function
getTitle(){
     echo
$this->title . PHP_EOL;
  }
}

$example = new Site;
$taobao = new Site;
$google = new Site;

// Memberfunktionen aufrufen, um den Titel und die URL festzulegen
$example->setTitle( Example);
$taobao->setTitle( Taobao);
$google->setTitle( Google Search);

$example->setUrl( 'www.example.com' );
$taobao->setUrl( 'www.taobao.com' );
$google->setUrl( 'www.google.com' );

// Memberfunktionen aufrufen, um den Titel und die URL abzurufen
$example->getTitle();
$taobao->getTitle();
$google->getTitle();

$example->getUrl();
$taobao->getUrl();
$google->getUrl();
?>

Beispiel ausführen »

Das Ausführen des obigen Codes erzeugt die folgende Ausgabe:

Example
淘宝
Google 搜索
www.example.com
www.taobao.com
www.google.com

PHP-Konstruktor

Ein Konstruktor ist eine spezielle Methode. Er wird hauptsächlich verwendet, um ein Objekt beim Erstellen zu initialisieren, das heißt, den Mitgliedsvariablen des Objekts Anfangswerte zuzuweisen. In der Anweisung, die das Objekt erstellt, zusammen mitnewdem Operator.

PHP 5 ermöglicht es Entwicklern, eine Methode in einer Klasse als Konstruktor zu definieren. Die Syntax lautet wie folgt:

void __construct ([ mixed $args [, $... ]] )

Im obigen Beispiel können wir die Variablen $url und $title durch den Konstruktor initialisieren:

function __construct( $par1, $par2 ) {
   $this->url = $par1;
   $this->title = $par2;
}

Jetzt müssen wir die Methoden setTitle und setUrl nicht mehr aufrufen:

Beispiel

$example = new Site('www.example.com', 'Example');
$taobao = new Site('www.taobao.com', 'Taobao');
$google = new Site('www.google.com', 'Google Search');

// Memberfunktionen aufrufen, um den Titel und die URL abzurufen
$example->getTitle();
$taobao->getTitle();
$google->getTitle();

$example->getUrl();
$taobao->getUrl();
$google->getUrl();

Beispiel ausführen »

Destruktor

Der Destruktor ist das Gegenteil des Konstruktors. Wenn ein Objekt seinen Lebenszyklus beendet (zum Beispiel, wenn die Funktion, in der sich das Objekt befindet, ihre Ausführung beendet hat), führt das System den Destruktor automatisch aus.

PHP 5 führte das Konzept eines Destruktors ein, ähnlich wie in anderen objektorientierten Sprachen. Seine Syntax lautet wie folgt:

void __destruct ( void )

Beispiel

<?php
class MyDestructableClass {
   function __construct() {
       print "构造函数\n";
       $this->name = "MyDestructableClass";
   }

   function __destruct() {
       print "销毁 " . $this->name . "\n";
   }
}

$obj = new MyDestructableClass();
?>

Das Ausführen des obigen Codes erzeugt die folgende Ausgabe:

构造函数
销毁 MyDestructableClass

Vererbung

PHP verwendet das Schlüsselwortextends, um eine Klasse zu erben. PHP unterstützt keine Mehrfachvererbung, das Format ist wie folgt:

class Child extends Parent {
   // 代码部分
}

Beispiel

Im Beispiel erbt die Klasse Child_Site von der Klasse Site und erweitert deren Funktionalität:

<?php 
// 子类扩展站点类别
class Child_Site extends Site {
   var $category;

    function setCate($par){
        $this->category = $par;
    }
  
    function getCate(){
        echo $this->category . PHP_EOL;
    }
}

Methodenüberschreibung

Wenn die von der Elternklasse geerbten Methoden den Anforderungen der Kindklasse nicht entsprechen, können sie überschrieben werden. Dieser Vorgang wird als Methodenüberschreibung (Override) bezeichnet.

Im Beispiel werden die Methoden getUrl und getTitle überschrieben:

function getUrl() {
   echo $this->url . PHP_EOL;
   return $this->url;
}
   
function getTitle(){
   echo $this->title . PHP_EOL;
   return $this->title;
}

Zugriffskontrolle

PHP implementiert die Zugriffskontrolle für Eigenschaften oder Methoden, indem es die Schlüsselwörter public, protected oder private davor setzt.

  • public:Auf public-Klassenmitglieder kann von überall aus zugegriffen werden.
  • protected:Auf protected-Klassenmitglieder kann von der Klasse selbst sowie von ihren Kindklassen und ihrer Elternklasse zugegriffen werden.
  • private:Auf private-Klassenmitglieder kann nur von der Klasse zugegriffen werden, in der sie definiert sind.

Zugriffskontrolle für Eigenschaften

Klasseneigenschaften müssen als public, protected oder private definiert werden. Wenn sie mit var definiert werden, werden sie als public behandelt.

<?php
/**
 * Define MyClass
 */
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}

$obj = new MyClass();
echo $obj->public; // 这行能被正常执行
echo $obj->protected; // 这行会产生一个致命错误
echo $obj->private; // 这行也会产生一个致命错误
$obj->printHello(); // 输出 Public、Protected 和 Private


/**
 * Define MyClass2
 */
class MyClass2 extends MyClass
{
    // 可以对 public 和 protected 进行重定义,但 private 而不能
    protected $protected = 'Protected2';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}

$obj2 = new MyClass2();
echo $obj2->public; // 这行能被正常执行
echo $obj2->private; // 未定义 private
echo $obj2->protected; // 这行会产生一个致命错误
$obj2->printHello(); // 输出 Public、Protected2 和 Undefined

?>

Zugriffskontrolle für Methoden

Methoden in einer Klasse können als public, private oder protected definiert werden. Wenn keines dieser Schlüsselwörter gesetzt ist, ist die Methode standardmäßig public.

<?php
/**
 * Define MyClass
 */
class MyClass
{
    // 声明一个公有的构造函数
    public function __construct() { }

    // 声明一个公有的方法
    public function MyPublic() { }

    // 声明一个受保护的方法
    protected function MyProtected() { }

    // 声明一个私有的方法
    private function MyPrivate() { }

    // 此方法为公有
    function Foo()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate();
    }
}

$myclass = new MyClass;
$myclass->MyPublic(); // 这行能被正常执行
$myclass->MyProtected(); // 这行会产生一个致命错误
$myclass->MyPrivate(); // 这行会产生一个致命错误
$myclass->Foo(); // 公有,受保护,私有都可以执行


/**
 * Define MyClass2
 */
class MyClass2 extends MyClass
{
    // 此方法为公有
    function Foo2()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate(); // 这行会产生一个致命错误
    }
}

$myclass2 = new MyClass2;
$myclass2->MyPublic(); // 这行能被正常执行
$myclass2->Foo2(); // 公有的和受保护的都可执行,但私有的不行

class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }

    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}

class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}

$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate 
                // Foo::testPublic
?>

Interfaces

Mithilfe von Schnittstellen können Sie angeben, welche Methoden eine Klasse implementieren muss, ohne die konkreten Inhalte dieser Methoden zu definieren.

Ein Interface wird mit deminterfaceSchlüsselwort definiert, genau wie beim Definieren einer Standardklasse, aber alle darin definierten Methoden sind leer.

Alle in einem Interface definierten Methoden müssen public sein; das ist eine Eigenschaft von Interfaces.

Um ein Interface zu implementieren, verwendet man denimplementsOperator. Die Klasse muss alle im Interface definierten Methoden implementieren, andernfalls wird ein fataler Fehler gemeldet. Eine Klasse kann mehrere Interfaces implementieren, wobei die Namen der mehreren Interfaces durch Kommas getrennt werden.

<?php

// 声明一个'iTemplate'接口
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}


// 实现接口
class Template implements iTemplate
{
    private $vars = array();
  
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
  
    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{' . $name . '}', $value, $template);
        }
 
        return $template;
    }
}

Konstanten

Man kann Werte, die in einer Klasse konstant bleiben, als Konstanten definieren. Beim Definieren und Verwenden von Konstanten wird das $-Symbol nicht benötigt.

Der Wert einer Konstante muss ein fester Wert sein; er kann keine Variable, keine Klasseneigenschaft, das Ergebnis einer mathematischen Operation oder ein Funktionsaufruf sein.

Seit PHP 5.3.0 kann eine Variable verwendet werden, um eine Klasse dynamisch aufzurufen. Der Wert dieser Variable darf jedoch kein Schlüsselwort sein (wie self, parent oder static).

Beispiel

<?php
class MyClass
{
    const constant = '常量值';

    function showConstant() {
        echo  self::constant . PHP_EOL;
    }
}

echo MyClass::constant . PHP_EOL;

$classname = "MyClass";
echo $classname::constant . PHP_EOL; // 自 5.3.0 起

$class = new MyClass();
$class->showConstant();

echo $class::constant . PHP_EOL; // 自 PHP 5.3.0 起
?>

Abstrakte Klassen

Jede Klasse, die mindestens eine als abstract deklarierte Methode enthält, muss selbst als abstract deklariert werden.

Eine als abstract definierte Klasse kann nicht instanziiert werden.

Als abstract definierte Methoden deklarieren nur ihre Aufrufmethode (Parameter) und können ihre konkrete funktionale Implementierung nicht definieren.

Beim Erben einer abstrakten Klasse muss die Kindklasse alle abstrakten Methoden in der Elternklasse definieren. Darüber hinaus muss die Zugriffskontrolle dieser Methoden dieselbe sein wie (oder weniger restriktiv als) die in der Elternklasse. Wenn beispielsweise eine abstrakte Methode als protected deklariert ist, sollte die in der Kindklasse implementierte Methode als protected oder public deklariert werden und darf nicht als private definiert werden.

<?php
abstract class AbstractClass
{
 // 强制要求子类定义这些方法
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    // 普通方法(非抽象方法)
    public function printOut() {
        print $this->getValue() . PHP_EOL;
    }
}

class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}

class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}

$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') . PHP_EOL;

$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?>

Das Ausführen des obigen Codes erzeugt die folgende Ausgabe:

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2

Darüber hinaus können Methoden der Kindklasse optionale Parameter enthalten, die in den abstrakten Methoden der Elternklasse nicht vorhanden sind.

Wenn beispielsweise eine Kindklasse einen optionalen Parameter definiert, der in der Deklaration der abstrakten Methode der Elternklasse nicht vorhanden ist, kann sie trotzdem normal ausgeführt werden.

<?php
abstract class AbstractClass
{
    // 我们的抽象方法仅需要定义需要的参数
    abstract protected function prefixName($name);

}

class ConcreteClass extends AbstractClass
{

    // 我们的子类可以定义父类签名中不存在的可选参数
    public function prefixName($name, $separator = ".") {
        if ($name == "Pacman") {
            $prefix = "Mr";
        } elseif ($name == "Pacwoman") {
            $prefix = "Mrs";
        } else {
            $prefix = "";
        }
        return "{$prefix}{$separator} {$name}";
    }
}

$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>

Ausgabeergebnis:

Mr. Pacman
Mrs. Pacwoman

Statisches Schlüsselwort

Das Deklarieren einer Klasseneigenschaft oder -methode als static ermöglicht den direkten Zugriff, ohne die Klasse zu instanziieren.

Auf statische Eigenschaften kann nicht über ein instanziiertes Objekt einer Klasse zugegriffen werden (auf statische Methoden jedoch schon).

Da statische Methoden nicht über ein Objekt aufgerufen werden müssen, ist die Pseudovariable $this in statischen Methoden nicht verfügbar.

Auf statische Eigenschaften kann von einem Objekt nicht mit dem ->-Operator zugegriffen werden.

Seit PHP 5.3.0 kann eine Variable verwendet werden, um eine Klasse dynamisch aufzurufen. Der Wert dieser Variable darf jedoch nicht die Schlüsselwörter self, parent oder static sein.

<?php
class Foo {
  public static $my_static = 'foo';
  
  public function staticValue() {
     return self::$my_static;
  }
}

print Foo::$my_static . PHP_EOL;
$foo = new Foo();

print $foo->staticValue() . PHP_EOL;
?>    

Das Ausführen des obigen Programms erzeugt die folgende Ausgabe:

foo
foo

Final-Schlüsselwort

PHP 5 fügte ein final-Schlüsselwort hinzu. Wenn eine Methode in der Elternklasse als final deklariert ist, kann die Kindklasse sie nicht überschreiben. Wenn eine Klasse als final deklariert ist, kann sie nicht vererbt werden.

Der folgende Code meldet bei der Ausführung einen Fehler:

<?php
class BaseClass {
   public function test() {
       echo "BaseClass::test() called" . PHP_EOL;
   }
   
   final public function moreTesting() {
       echo "BaseClass::moreTesting() called"  . PHP_EOL;
   }
}

class ChildClass extends BaseClass {
   public function moreTesting() {
       echo "ChildClass::moreTesting() called"  . PHP_EOL;
   }
}
// 报错信息 Fatal error: Cannot override final method BaseClass::moreTesting()
?>

Aufrufen des Elternkonstruktors

PHP ruft den Konstruktor der Elternklasse nicht automatisch im Konstruktor der Kindklasse auf. Um den Konstruktor der Elternklasse auszuführen, müssen Sie ihn im Konstruktor der Kindklasse aufrufen:parent::__construct() 。

<?php
class BaseClass {
   function __construct() {
       print "BaseClass 类中构造方法" . PHP_EOL;
   }
}
class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();  // 子类构造方法不能自动调用父类的构造方法
       print "SubClass 类中构造方法" . PHP_EOL;
   }
}
class OtherSubClass extends BaseClass {
    // 继承 BaseClass 的构造方法
}

// 调用 BaseClass 构造方法
$obj = new BaseClass();

// 调用 BaseClass、SubClass 构造方法
$obj = new SubClass();

// 调用 BaseClass 构造方法
$obj = new OtherSubClass();
?>

Das Ausführen des obigen Programms erzeugt die folgende Ausgabe:

BaseClass 类中构造方法
BaseClass 类中构造方法
SubClass 类中构造方法
BaseClass 类中构造方法
Andere Erweiterungen