# PHP继承:extends 与 parent:: 的使用
PHP作为一门面向对象编程语言,继承是其核心特性之一。掌握extends关键字和parent::的使用方法,能让你写出更优雅、可维护的代码。本文将详细介绍PHP继承机制的实际应用。
## 一、继承基础:extends关键字
继承允许一个类(子类)继承另一个类(父类)的属性和方法,这是代码复用的重要手段。
```php
class Animal {
public $name;
public function eat() {
echo $this->name . " is eating.\n";
}
}
class Dog extends Animal {
public function bark() {
echo $this->name . " is barking.\n";
}
}
$dog = new Dog();
$dog->name = "Buddy";
$dog->eat(); // 输出: Buddy is eating.
$dog->bark(); // 输出: Buddy is barking.
```
在这个例子中:
- `Dog`类通过`extends Animal`继承了`Animal`类
- `Dog`获得了`Animal`的所有public和protected属性和方法
- `Dog`还可以扩展自己的方法(如`bark()`)
## 二、方法重写与parent::调用
子类可以重写父类的方法,但有时我们需要在子类中调用父类的原始实现。
```php
class Animal {
public function makeSound() {
echo "Some generic animal sound\n";
}
}
class Cat extends Animal {
public function makeSound() {
parent::makeSound(); // 先调用父类方法
echo "Meow!\n"; // 然后添加猫特有的行为
}
}
$cat = new Cat();
$cat->makeSound();
// 输出:
// Some generic animal sound
// Meow!
```
使用`parent::`的几种场景:
1. **扩展父类方法**:在保留父类行为的基础上添加新功能
2. **部分重写**:只修改父类方法的部分行为
3. **构造函数调用**:子类构造函数中初始化父类
## 三、构造函数的继承
构造函数(`__construct`)的继承需要特别注意:
```php
class Vehicle {
protected $brand;
public function __construct($brand) {
$this->brand = $brand;
}
public function getInfo() {
return "Brand: " . $this->brand;
}
}
class Car extends Vehicle {
private $model;
public function __construct($brand, $model) {
parent::__construct($brand); // 必须先调用父类构造函数
$this->model = $model;
}
public function getInfo() {
return parent::getInfo() . ", Model: " . $this->model;
}
}
$car = new Car("Toyota", "Corolla");
echo $car->getInfo(); // 输出: Brand: Toyota, Model: Corolla
```
关键点:
- 子类构造函数中必须先调用`parent::__construct()`
- 这样可以确保父类属性正确初始化
- 然后才能初始化子类特有的属性
## 四、访问控制与继承
PHP的访问修饰符影响继承行为:
1. **public**:在任何地方可访问
2. **protected**:仅类内部和子类可访问
3. **private**:仅类内部可访问
```php
class Base {
public $public = 'public';
protected $protected = 'protected';
private $private = 'private';
public function show() {
echo $this->private . "\n"; // 可访问
}
}
class Derived extends Base {
public function test() {
echo $this->public . "\n"; // 可访问
echo $this->protected . "\n"; // 可访问
// echo $this->private . "\n"; // 会报错
}
}
$obj = new Derived();
$obj->test();
echo $obj->public . "\n"; // 可访问
// echo $obj->protected; // 会报错
// echo $obj->private; // 会报错
```
## 五、实际开发中的继承技巧
1. **避免过度继承**:继承层次不宜过深,通常不超过3层
2. **组合优于继承**:考虑是否可以用组合代替继承
3. **final类和方法**:用`final`关键字防止类被继承或方法被重写
4. **抽象类和接口**:合理使用抽象类和接口设计继承体系
## 六、常见问题解答
**Q:什么时候应该使用继承?**
A:当两个类之间存在"是一种(is-a)"关系时使用继承。例如:Dog是一种Animal。
**Q:parent::和$this有什么区别?**
A:`parent::`用于调用父类方法,`$this`指当前对象实例。在子类中,`parent::method()`调用父类实现,`$this->method()`可能调用子类重写后的方法。
**Q:为什么有时候调用parent::会报错?**
A:可能原因:
1. 父类没有该方法
2. 父类方法是private的
3. 调用方式不正确(如静态调用非静态方法)
掌握PHP继承机制,能让你构建更灵活的代码结构。合理使用extends和parent::,让你的OOP代码更加专业和可维护。