PHP - 繼承:初學者指南

您好,未來的 PHP 巔峰大師!今天,我們將踏上一段令人興奮的旅程,探索 PHP 繼承的神秘世界。別擔心你對編程是新手——我會成為你的友好導遊,一步步地解釋一切。所以,來一杯咖啡(或者茶,如果你喜歡的話),我們一起來深入探討吧!

PHP - Inheritance

繼承是什麼?

繼承就像是 PHP 中類的家族樹。正如你可能繼承了你祖母的眼睛或你父親的幽默感,在編程中,一個類可以從另一個類繼承屬性和方法。這個概念幫助我們寫出更有組織性且可重用的代碼。

這樣想:想像你正在創建一款具有不同角色的電子遊戲。所有角色可能都會有一些基本特徵(比如有名字或生命值),但每種類型的角色(如戰士或法師)可能會有獨特的技能。繼承讓我們能夠在基礎類中定義這些共同特徵,然後創建特定的角色類,它們繼承這些特徵並添加自己獨特的功能。

基本繼承範例

讓我們從一個簡單的範例開始,看看 PHP 中繼承是如何工作的。

class Animal {
public $name;

public function __construct($name) {
$this->name = $name;
}

public function speak() {
echo "The animal makes a sound.";
}
}

class Dog extends Animal {
public function speak() {
echo $this->name . " barks: Woof woof!";
}
}

$myDog = new Dog("Buddy");
$myDog->speak(); // 輸出: Buddy barks: Woof woof!

在這個範例中,我們有两个類:AnimalDogDog 類繼承自 Animal 類,這意味著它繼承了 Animal 類的所有屬性和方法。

讓我們來分解一下:

  1. 我們定義了一個基礎的 Animal 類,具有 $name 屬性和 speak() 方法。
  2. 我們創建了一個 Dog 類,使用 extends 關鍵字繼承 Animal
  3. Dog 類覆寫了 speak() 方法並提供了自己的實現。
  4. 我們創建了一個名為 "Buddy" 的新 Dog 對象並調用了它的 speak() 方法。

Dog 類從 Animal 繼承了 $name 屬性,但提供了自己的 speak() 方法版本。這被稱為方法覆寫,它是繼承的一個強大特性。

繼承和訪問修飾符

現在,讓我們來討論一下繼承是如何與不同的訪問修飾符(public、protected 和 private)一起工作的。

class Vehicle {
public $brand;
protected $model;
private $serialNumber;

public function __construct($brand, $model, $serialNumber) {
$this->brand = $brand;
$this->model = $model;
$this->serialNumber = $serialNumber;
}

public function getInfo() {
return "Brand: " . $this->brand . ", Model: " . $this->model;
}

protected function getSerialNumber() {
return $this->serialNumber;
}
}

class Car extends Vehicle {
public $doors;

public function __construct($brand, $model, $serialNumber, $doors) {
parent::__construct($brand, $model, $serialNumber);
$this->doors = $doors;
}

public function getFullInfo() {
return $this->getInfo() . ", Doors: " . $this->doors . ", SN: " . $this->getSerialNumber();
}
}

$myCar = new Car("Toyota", "Corolla", "ABC123", 4);
echo $myCar->getFullInfo();
// 輸出: Brand: Toyota, Model: Corolla, Doors: 4, SN: ABC123

在這個範例中:

  1. Vehicle 類具有不同訪問修飾符的屬性。
  2. Car 類繼承 Vehicle 並添加了自己的屬性($doors)。
  3. Car 類可以訪問 Vehicle 的 public 和 protected 成員,但不能訪問 private 成員。
  4. 我們使用 parent::__construct() 調用父類的構造函數。

記住:

  • Public 成員在任何地方都可以訪問。
  • Protected 成員在類及其子類中可以訪問。
  • Private 成員只能在定義它的類中訪問。

繼承中的構造函數

讓我們更深入地了解構造函數在繼承中是如何工作的:

class Shape {
protected $color;

public function __construct($color) {
$this->color = $color;
echo "Shape constructor called.<br>";
}
}

class Circle extends Shape {
private $radius;

public function __construct($color, $radius) {
parent::__construct($color);
$this->radius = $radius;
echo "Circle constructor called.<br>";
}

public function getInfo() {
return "A {$this->color} circle with radius {$this->radius}";
}
}

$myCircle = new Circle("red", 5);
echo $myCircle->getInfo();

輸出:

Shape constructor called.
Circle constructor called.
A red circle with radius 5

這裡發生了什麼:

  1. 當我們創建一個 Circle 對象時,PHP 首先調用 Shape 構造函數(父類)。
  2. 然後它調用 Circle 構造函數。
  3. 我們使用 parent::__construct($color) 確保 Shape 構造函數被調用,並設置 $color 屬性。
  4. 最後,我們設置了 Circle 類特有的 $radius 屬性。

這樣可以確保父類和子類都被正確初始化。

方法參考表

這裡是我們在範例中使用的方法的便捷表格:

方法 描述
__construct() 構造函數,當創建對象時調用
speak() 方法讓動物發出聲音
getInfo() 方法獲取車輛的基本信息
getSerialNumber() Protected 方法獲取車輛的序號
getFullInfo() 方法獲取汽車的完整信息

結論

繼承是 PHP 中的強大工具,它讓我們能夠創建類的層次結構,促進代碼的重用和組織。記住,這就像是用 LEGO 樓件一樣——你從一個基礎部件開始,然後在上麵添加更專業的部件。

隨著你繼續 PHP 的學習之旅,你會發現更多使用繼承的令人興奮的方式。繼續練習,很快你就能夠輕鬆地創建複雜且高效的面向對象程序!

祝你好運,未來的 PHP 大師!??‍??‍?

Credits: Image by storyset