首页 / PHP 入门教程 / PHP 面向对象进阶

PHP 入门教程

PHP 面向对象进阶

本教程共 65 篇 · 第 20 篇 · 更新于 2026-07-24 · 约 5 分钟阅读

PHPPHP8继承静态成员类常量方法重写

20. PHP 面向对象进阶

本节目标:掌握继承、静态成员和类常量。学完你能构建层次化的类结构,写出更高效的代码。

20.1 继承

继承允许子类复用父类的属性和方法:

<?php
class Animal {
    public string $name;
    
    public function __construct(string $name) {
        $this->name = $name;
    }
    
    public function speak(): string {
        return "某种声音";
    }
    
    public function info(): string {
        return "这是{$this->name}";
    }
}

// Dog 继承 Animal
class Dog extends Animal {
    public function speak(): string {
        return "汪汪汪";
    }
}

// Cat 继承 Animal
class Cat extends Animal {
    public function speak(): string {
        return "喵喵喵";
    }
}

$dog = new Dog("大黄");
echo $dog->info();    // 这是大黄
echo $dog->speak();   // 汪汪汪

$cat = new Cat("小花");
echo $cat->speak();   // 喵喵喵
?>
Tip

继承表达的是”是一种”(is-a)关系。Dog 是一种 Animal,所以 Dog extends Animal 是合理的。

20.2 方法重写与访问控制

子类可以重写父类方法,但访问权限不能更严格:

<?php
class ParentClass {
    public function publicMethod(): void {}
    protected function protectedMethod(): void {}
    private function privateMethod(): void {}  // 子类无法访问
}

class ChildClass extends ParentClass {
    // 可以重写,保持 public
    public function publicMethod(): void {}
    
    // 可以改为 public(更宽松)
    public function protectedMethod(): void {}
    
    // 不能改为 protected 或 private(更严格)
    // protected function publicMethod(): void {}  // 错误!
}
?>

20.3 调用父类方法

<?php
class Employee {
    protected string $name;
    protected float $salary;
    
    public function __construct(string $name, float $salary) {
        $this->name = $name;
        $this->salary = $salary;
    }
    
    public function getInfo(): string {
        return "{$this->name},薪资:{$this->salary}";
    }
}

class Manager extends Employee {
    private float $bonus;
    
    public function __construct(string $name, float $salary, float $bonus) {
        parent::__construct($name, $salary);  // 调用父类构造
        $this->bonus = $bonus;
    }
    
    public function getInfo(): string {
        $base = parent::getInfo();  // 调用父类方法
        return "$base,奖金:{$this->bonus}";
    }
}

$manager = new Manager("张三", 10000, 5000);
echo $manager->getInfo();  // 张三,薪资:10000,奖金:5000
?>
Note

如果子类定义了构造函数,父类构造函数不会自动调用,必须用 parent::__construct() 显式调用。

20.4 final 关键字

final 阻止类被继承或方法被重写:

<?php
// final 类不能被继承
final class Config {
    public static string $version = "1.0";
}

// class MyConfig extends Config {}  // 错误!

class Base {
    // final 方法不能被重写
    final public function critical(): void {
        echo "核心逻辑,不允许修改";
    }
    
    public function normal(): void {
        echo "可以重写";
    }
}

class Derived extends Base {
    // public function critical(): void {}  // 错误!
    
    public function normal(): void {
        echo "已重写";
    }
}
?>

20.5 静态成员

静态属性和方法属于类本身,不需要创建对象:

<?php
class Counter {
    public static int $count = 0;
    
    public static function increment(): void {
        self::$count++;
    }
    
    public static function getCount(): int {
        return self::$count;
    }
}

// 通过类名直接访问
Counter::increment();
Counter::increment();
echo Counter::getCount();  // 2

// 静态属性在内存中只有一份
$c1 = new Counter();
$c2 = new Counter();
Counter::increment();
echo Counter::getCount();  // 3
?>
Tip

静态方法内不能使用 $this,因为没有对象实例。使用 self:: 访问静态成员。

单例模式示例

<?php
class Database {
    private static ?self $instance = null;
    
    // 私有构造,防止外部 new
    private function __construct() {}
    
    public static function getInstance(): self {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

$db1 = Database::getInstance();
$db2 = Database::getInstance();
var_dump($db1 === $db2);  // true(同一个实例)
?>

20.6 类常量

<?php
class Math {
    public const PI = 3.14159;
    public const E = 2.71828;
    
    // PHP 8.1+ final 常量(不能被重写)
    final public const VERSION = "2.0";
}

// 通过类名访问
echo Math::PI;

// 子类可以重写常量(除非标记为 final)
class AdvancedMath extends Math {
    public const PI = 3.14159265359;
}

echo AdvancedMath::PI;
?>

20.7 $this vs self vs static

关键字指向用途
$this当前对象实例访问实例属性和方法
self当前类访问当前类的静态成员、常量
static当前类(运行时解析)后期静态绑定
<?php
class ParentClass {
    public static string $name = "Parent";
    
    public static function who(): string {
        return self::$name;      // 编译时绑定,始终返回 Parent
    }
    
    public static function whoDynamic(): string {
        return static::$name;    // 运行时绑定,根据调用者决定
    }
}

class ChildClass extends ParentClass {
    public static string $name = "Child";
}

echo ParentClass::who();          // Parent
echo ChildClass::who();           // Parent(self 绑定到定义类)
echo ChildClass::whoDynamic();    // Child(static 绑定到调用类)
?>
Note

static:: 称为”后期静态绑定”,在需要子类重写静态行为时使用。这是 PHP 5.3 引入的重要特性。


来源:参考了 w3cschool「PHP 面向对象」、runoob「PHP 面向对象」以及 php.net 官方文档,综合改写后所得。