在 PHP 中,类的继承(继承)是一种机制,允许一个类继承另一个类的属性和方法,从而实现代码的重用和扩展。继承可以帮助你创建一个基于现有类的新类,保留原有类的特性并增加或修改其功能。
class Animal { public $name='dongwu'; protected $age=1; private $birth='2024'; } class Cat extends Animal{} //使用extends 关键字继承父类 注意花括号后面没有分号 var_dump(new Animal); var_dump(new Cat);
var_dump 2个类看看内容,除了名字不同,内容都是一样的。
[Running] D:\ceshi.test\3.php"
object(Animal)#1 (3) {
["name"]=>
string(6) "dongwu"
["age":protected]=>
int(1)
["birth":"Animal":private]=>
string(4) "2024"
}
object(Cat)#1 (3) {
["name"]=>
string(6) "dongwu"
["age":protected]=>
int(1)
["birth":"Animal":private]=>
string(4) "2024"
}
接下来尝试调用Animal类的变量
class Animal { public $name='dongwu'; protected $age=1; private $birth='2024'; } class Cat extends Animal{} $obj = new Cat; echo $obj->name; //只有这个public 的name可以被打印 echo $obj->age; //虽然是子类可以拿到,但是是在类的内部可以拿到,外部想要拿到的话,需要使用函数的方式拿到 echo $obj->birth; //私有类型的,子类无法拿到
接下来演示如何拿到protected的age
class Animal { public $name='dongwu'; protected $age=1; private $birth='2024'; } class Cat extends Animal{ function getage(){ //使用方法拿到age,由此可见protected类型的变量只能在类的内部拿到 echo $this->age; } } $obj = new Cat; echo $obj->getage();
回显如下:
[Running] D:\ceshi.test\3.php"
1
接下来再看下面的这段代码
class Animal { protected $name; public function __construct($name){ $this->name =$name; //通过构造函数赋值给类里面的name变量 } public function eat(){ echo $this->name. ' is eatting'; } } class Cat extends Animal{ public function meow(){ //子类自有的方法 echo $this->name.'is meowing'; } } $cat = new Cat('lanmao'); var_dump($cat); $cat->eat(); $cat->meow();
回显如下:
[Running] D:\ceshi.test\3.php"
object(Cat)#1 (1) {
["name":protected]=>
string(6) "lanmao"
}
lanmao is eattinglanmaois meowing
由此可见 vardump只能打印出父类的变量(属性),而不能打印出方法。实际是可以继承过来的,只是无法通过vardump打印出来。比如父类的构造方法和其他方法都被继承了过来。
类方法和属性(变量)的重写
如果从父类继承的方法或属性不能满足子类的需求,可以对其进行改写,下面的这段代码中父类虽然有了eat方法,但是子类在继承后又重写了eat方法,所以会执行子类的eat方法而忽略父类的eat方法
class Animal { protected $name; public function __construct($name){ $this->name =$name; } public function eat(){ echo $this->name. ' is eatting'; //虽然父类中有了eat方法 } } class Cat extends Animal{ public function eat(){ echo $this->name. ' is eatting2'; //子类重写了eat方法后,会忽略父类中的eat方法 } public function meow(){ echo $this->name.'is meowing'; } } $cat = new Cat('lanmao'); $cat->eat();
回显如下:
[Running] D:\ceshi.test\3.php"
lanmao is eatting2
同样,属性(变量)也可以重写,看下面的例子
class Animal { protected $name='fish'; //初始值设置为fish public function eat(){ echo $this->name. ' is eatting'; } } class Cat extends Animal{ protected $name='fox'; //子类中重写属性 public function meow(){ echo $this->name.' is meowing'; } } $cat = new Cat(); $cat->meow();
回显如下:
[Running] D:\ceshi.test\3.php"
foxis meowing
final 关键字
作用:
防止类被集成
防止类的方法被重写
先看阻止类方法重写
class Animal { protected $name; public function __construct($name){ $this->name =$name; } final public function eat(){ //类方法前加上final,则这个类无法被继承 echo $this->name. ' is eatting'; } } class Cat extends Animal{ public function eat(){ echo $this->name. ' is eatting2'; } public function meow(){ echo $this->name.'is meowing'; } } $cat = new Cat('lanmao');$cat->eat();
回显如下:
[Running] D:\ceshi.test\3.php
PHP Fatal error: Cannot override final method Animal::eat() in D:\phpstudy_pro\WWW\ceshi.test\3.php on line 30
Fatal error: Cannot override final method Animal::eat() in D:\phpstudy_pro\WWW\ceshi.test\3.php on line 30
再看阻止类继承
final class Animal { //此处加上final来阻止类被继承 protected $name; public function __construct($name){ $this->name =$name; } public function eat(){ echo $this->name. ' is eatting'; } } class Cat extends Animal{ public function eat(){ echo $this->name. ' is eatting2'; } public function meow(){ echo $this->name.'is meowing'; } } $cat = new Cat('lanmao');$cat->eat();
回显如下:
[Running] D:\ceshi.test\3.php"
PHP Fatal error: Class Cat may not inherit from final class (Animal) in D:\phpstudy_pro\WWW\ceshi.test\3.php on line 30
Fatal error: Class Cat may not inherit from final class (Animal) in D:\phpstudy_pro\WWW\ceshi.test\3.php on line 30
在 PHP 中,可以通过
parent::
关键字在子类中调用父类的方法。例如:class ParentClass { public function greet() { echo "Hello from ParentClass!"; } } class ChildClass extends ParentClass { public function greet() { // 调用父类的 greet() 方法 parent::greet(); echo " And hello from ChildClass!"; } } $child = new ChildClass(); $child->greet();
回显如下:
[Running] D:\ceshi.test\6.php"
Hello from ParentClass! And hello from ChildClass!
继续看调用父类的构造函数
class ParentClass { public function __construct($name) { echo "ParentClass constructor with name: $name"; //父类的构造函数有一个name传进来 } } class ChildClass extends ParentClass { public function __construct($name, $age) { // 调用父类的构造函数 parent::__construct($name); echo "ChildClass constructor with age: $age"; //不仅能输出自己的构造函数,还能输出父类的构造函数 } } $child = new ChildClass('Alice', 25);
回显如下:
[Running] D:\ceshi.test\6.php"
ParentClass constructor with name: Alice
ChildClass constructor with age: 25
同样,也可以重写父类继承过来的构造函数
class ParentClass { public function __construct($name) { echo "ParentClass constructor with name: $name"; } } class ChildClass extends ParentClass { public function __construct($age) { // 直接重写继承自父类的构造函数,需要注意的是父类的构造函数本身不会受到影响 echo "ChildClass constructor with age: $age"; } }
回显如下:
[Running] D:\ceshi.test\6.php"
ChildClass constructor with age: 25
静态延迟绑定static
是指在运行时根据实际调用的类来确定静态方法或属性的绑定
static::$name
来看下面这段代码
在这个示例中,
self::$name
和 static::$name
的行为是不同的。self::$name
在任何情况下都指向 Animal
类的 $name
属性,而 static::$name
使用的是静态延迟绑定,这意味着它会指向当前调用 eat()
方法的类的 $name
属性。由于你是通过 Animal::eat()
调用的,结果如下:<?php class Animal { protected static $name = 'Animal'; public static function eat() { echo self::$name . ' is eating'; echo '----'; echo static::$name . ' is eating'; } } Animal::eat(); ?>
[Running] D:\ceshi.test\6.php"
Animal is eating----Animal is eating
如果你有子类
Dog
继承自 Animal
,并重写 $name
属性,调用 Dog::eat()
将会展示不同的结果:<?php class Animal { protected static $name = 'Animal'; public static function eat() { echo self::$name . ' is eating'; echo '----'; echo static::$name . ' is eating'; } } class Dog extends Animal { protected static $name = 'Dog'; } Dog::eat(); ?>
[Running] D:\phpstudy_pro\Extensions\php\php7.3.4nts\php.exe "d:\phpstudy_pro\WWW\ceshi.test\6.php"
Animal is eating----Dog is eating
此时
static::$name
使用静态延迟绑定,指向实际调用方法的类 Dog
中的 $name
属性。由于 Dog
类覆盖了 Animal
类的 $name
属性,所以 static::$name
输出的是 Dog.这就是静态绑定
分类:
PHP8
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)