5.0 继承
5.1 继承的概念
在现实生活中,继承一般指的是子女继承父辈的财产。在程序中,继承描述的是事物之间的所属关系,通过继承可以使许多事物之间形成一种关系体系 。
例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物。同理,波斯猫和田园猫继承自猫,而阿拉斯加和哈士奇继承自动物,这些动物之间会形成一个继承体系, 具体下图所示。
在PHP中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法。
在程序中,如果想声明一个类继承另一个类,需要使用extends 关键字,具体语法格式如下:
1 class 子类名 extends 父类名{
2 //类体
3 }
为了让初学者更好理解继承,接下来通过一个案例来介绍子类如何继承父类
例5-11
1 <?php
2 //定义Animal类
3 class Animal{
4 public $name;
5 public function shout(){
6 echo "动物发出叫声<br>";
7 }
8 }
9 //定义Dog类继承自Animal类
10 class Dog extends Animal{
11 public function printName(){
12 echo "name=".$this->name;
13 }
14 }
15 $dog=new Dog();
16 $dog->name="阿拉斯加";
17 $dog->shout();
18 $dog->printName();
19 ?>
运行结果
在例5-11中,Dog类通过extends关键字继承了Animal类,这样Dog类便是Animal类的子类。从运行结果不难看出。子类虽然没有定义name属性和shout()方法,但是却能访问这两个成员。这就说明,子类在继承父类的时候,会自动拥有父类的成员。
注意:在PHP中只能实现单继承,也就是说子类只能继承一个父类(是指直接继承).
5.2 重写父类方法
在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。需要注意的是,在子类中重写的方法需要和父类被重写的方法具有相同的方法名参数。
例程5-11中,Dog类从Animal类继承了shout()方法, 该方法在被调用时会打印“动物发出叫声”。这明显不能描述一种具体动物的叫声,Dog 类对象表示犬类。发出的叫声应该是“汪汪”。为了解决这个问题。可以在Dog类中重写父类Animal中的shout()方法。具体代码如例5-12所示。
例5-12
1 <?php
2 //定义Animal类
3 class Animal{
4 //动物叫的方法
5 public function shout(){
6 echo "动物发出叫声";
7 }
8 }
9 //定义Dog类继承自Animal类
10 class Dog extends Animal{
11 //定义狗叫的方法
12 public function shout(){
13 echo '汪汪......';
14 }
15 }
16 $dog=new Dog();
17 $dog->shout();
18 ?>
运行结果
例5-12中,定义了Dog类并且继承自Animal类在子类Dog中定又了一个shout()方法对父类的方法进行重写。从运行结果可以看出,在调用Dog类对象的shout()方法时,只会调用子类重写的该方法,并不会调用父类的shout()方法。
如果想要调用父类中被重写的方法,就需要使用parent关键字, parent关键字用于访向父类的成员。由于parent关键字引用的是一个类而不是一个对象,因此需要使用范围解析操作符(::)。接下来通过一个案例来演示如何使用patent关键字访问父类成员方法,如例5-13所示
例5-13
1 <?php
2 //定义Animal类
3 class Animal{
4 //动物叫的方法
5 public function shout(){
6 echo "动物发出叫声";
7 }
8 }
9 //定义Dog类继承自Animal类
10 class Dog extends Animal{
11 //定义狗叫的方法
12 public function shout(){
13 parent::shout();//调用父类被重写的方法
14 echo "<br>";
15 echo '汪汪......';
16 }
17 }
18 $dog=new Dog();
19 $dog->shout();
20 ?>
运行结果
例5-13中。定义了一个Dog类继承Animal类.并重写了Animal类的shout()方法。在子类Dog的shout()方法中使用 parent::shout()调用了父类被重写的方法。从运行结果可以看出,子类通过parent关键字可以成功地访问父类的成员方法。
5.3 fnal关键字
继承为程序编写带来了巨大的灵话性,但有时可能需要在继承的过程中保证某些类或法不技改变,此时就需要使用final关键字。fnal 关键字有“无法改变”或者“最终”的含义因此被final修饰的类和成员方法不能被修改。接下来将针对final关键字进行详细讲解。
1. final关键字修饰类
PHP中的类被final关键字修饰后,该类将不可以被继承,也就是不能够派生子类。接下来通过一个案例来验证,如例5-14所示。
例5-14
1 <?php
2 //定义Animal类
3 final class Animal {
4 //程序代码
5 }
6 class Bird extends Animal {
7 //程序代码
8 }
9 $bird=new Animal();
10 ?>
运行结果 程序发生报错
例5-14中,由于Animal类被final关键字所修饰.因此,当Bind类继承Animal类时,编译出现了 无法从最终Animal类进行继继承的错误。由此可见,被final关键字修饰的类为最终类,不能被其他类继承。
1. final关键字修饰方法
当一个类的方法被final关键字修饰后,这个类的子类不能重写该方法。接下来通过一个案例来验证,如例5-15所示。
例5-15
1 <?php
2 class Animal{
3 final public function shout(){
4 //方法体为空
5 }
6 }
7 class Bird extends Animal{
8 public function shout(){
9 //方法体为空
10 }
11 }
12 $bird=new Animal();
13 $bird->shout();
14 ?>
程序报错,运行结果