首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 物件導向核心觀念 (2):static 與 private 衝突、$this 在靜態方法限制、可見性與繼承實戰

     編輯:PHP 相關知識

經典錯誤:`Using $this when not in object context`

<?php
class Trones {
    public static $fire = 'I am fire.';
    public $water = 'I am water';

    public static function getFire() {
        return $this->fire; // ❌ Fatal Error
    }

    public static function getWater() {
        return self::$water; // ❌ Fatal Error: 非靜態屬性不可用 self::
    }

    public static function getFireCorrect() {
        return self::$fire; // ✅ 靜態方法只能存取靜態屬性
    }
}

Trones::getFireCorrect(); // 正常
$obj = new Trones();
$obj->fire; // Notice: 靜態屬性不可用 -> 操作
> **鐵律**:**靜態方法中不可使用 `$this`**,只能用 `self::` 或 `static::` (晚期靜態綁定) 存取**靜態成員**。

可見性控制:public / protected / private

關鍵字類別內部繼承類別外部
`public`✅✅✅
`protected`✅✅❌
`private`✅❌❌

static + private 組合陷阱


class Trones {
    protected $fire = 'fire';
    public $water = 'water';
    private static $trones = 'Trones';

    protected function getFire() { return $this->fire; }

    public static function theDragon() {
        return __METHOD__ . ' uses ' . $this->getFire() . ' gets ' . self::getTrones(); // ❌ $this 在 static
    }

    public static function getWater() { return __METHOD__; }

    private static function getTrones() { return self::$trones; }
}

class Kings extends Trones {
    public static function sevenKing() {
        return self::getTrones(); // ❌ private 父類別方法不可繼承
    }
}

class People extends Trones {
    public static function thePeople() {
        return self::getTrones(); // ❌ 同上
    }
}
> **解決**: > 1. 靜態方法移除 `$this->getFire()` 呼叫。 > 2. 父類別 `private static` 改為 `protected static` 讓子類別可用 `parent::` 或 `static::`。 > 3. 子類別覆寫靜態方法時,`self::` 指向**當前類別**,`static::` 指向**實際調用類別** (晚期靜態綁定)。

晚期靜態綁定 (LSB) 示範


class A {
    public static function who() { echo __CLASS__; }
    public static function test() { self::who(); }    // 輸出 A
    public static function testLSB() { static::who(); } // 輸出實際調用類別
}

class B extends A {
    public static function who() { echo __CLASS__; }
}

B::test();    // A (self:: 綁定寫死)
B::testLSB(); // B (static:: 動態解析)

介面、抽象類別、Trait 選擇指南

  • `interface`:定義**契約**,多實作、無狀態。
  • `abstract class`:提供**部份實作**、共享屬性/邏輯、單繼承。
  • `trait`:**橫向復用**程式碼片段,無實例化、無屬性 (PHP 8.0+ 可有屬性)。

原文摘自 warcraft

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved