在PHP中,多态是最常用到的一种特性。所谓多态,是指同一个东西不同形态的展示。在PHP中,我们这样定义多态,一个类被多个子类继承,如果这个类的某个方法在多个子类中表现不同的功能,那么这种行为我们就称其为多态的实现。
多态的实现必须要满足三个条件
- 子类继承父类
- 子类重写父类的方法
- 父类引用指向子类对象
到这里我们需要引入一个概念:抽象类。
抽象类中只定义(或部分实现)子类需要的方法。子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化 。
- 抽象类至少要有一个抽象方法声明关键字 abstract
- 抽象类必须要有抽象方法,方法中没有大括号(函数体)
- 抽象方法只是声明了其调用方式(参数),不实现具体的功能,由子类实现抽象类中所有的方法
- 如果抽象方法有参数,那么子类的实现也必须有相同的参数个数
- 抽象类不能被实例化,它的意义在于被扩展
<?php
abstract class MyAbsClass
{
abstract public function func();
//抽象类必须要有一个抽象的方法,含有抽象方法的类也必须是抽象类
//定义一个抽象方法之后,在定义其他的属性和方法和普通的类方式一样
public $name = 'lilei';
public $age = 13;
public function test(){
echo 'hello world';
}
}
class ChildClass extends MyAbsClass
{
public function func(){
echo $this->name;
}
//类也可以继承抽象类,但是必须同时实现抽象类的方法,之后才可以进行类的实例化
}
class MyClass extends MyAbsClass
{
public function func(){
echo $this->age;
}
//类也可以继承抽象类,但是必须同时实现抽象类的方法,之后才可以进行类的实例化
}
abstract class SonClass extends MyAbsClass
{
//抽象类可以继承另一个抽象类
}
$obj1 = new ChildClass();
$obj1->func();
$ojb2 = new SonClass();
$ojb2->func();
修饰关键字顺序
- 类的属性和方法必须添加访问修饰符(public、private和protected)
- abstract 以及 final 必须声明在访问修饰符之前
- static 必须声明在访问修饰符之后
接口
接口的意义所在,即定义一些通用的方法,好多类都同时实现这些方法,但是实现的方法不一样。接口中定义的所有方法,实现接口的类中必须全部实现,不能实现其中几个,只能全部实现,下面程序中的checkWork方法是判断某个对象是否实现了一个接口。
- 使用接口(interface),可以指定某个类的必须实现哪些方法,但不需要定义这些方法的具体内容,接口中也可以定义常量。
- 接口关键字 interface 接口里面不能有方法的具体定义和变量属性,只能是声明了方法名称和常量。
- 实现关键字 implements 一个类可以实现多个接口,接口也可以继承 关键字 extends
TIPS
- 接口里定义的方法都是抽象方法,只有方法名称,没有方法体,不需要加抽象关键字 abstract。
- 实现多个接口时,接口中的方法不能有重名。
- 接口也可以继承,通过使用 extends 操作符
- 类要实现接口,必须使用和接口中所定义的方法完全一致的方式。否则会导致致命错误。
- 定义的方法都是public公有的类型
类型运算符
- instanceof 用于确定一个PHP变量是否属于某一类class的实例
- instanceof也可以用于确定一个变量是不是继承自某一父类的子类的实例
- instanceof也可以用于确定一个变量是不是实现了某个接口的类的实例
<?php
interface Work
{
public function worker($job);
}
//Programmer类实现了Work接口
class Programmer implements Work
{
public function worker($job){
echo 'The programmer is ' . $job . '<br/>';
}
}
// ProductManager类也实现了Work接口
class ProductManager implements Work {
public function worker($job){
echo 'The product manager is ' . $job;
}
}
// 不同的类可以实现同一个接口
$coding = new Programmer();
$coding->worker("coding");
$holiday = new ProductManager();
$holiday->worker("play game");
// 实现了某个接口的类必须提供接口中定义的方法
// 不能用接口创建对象,但是能够判断某个对象是否实现了某个接口
var_dump($coding instanceof Work); // 判断某个对象是否实现了某个接口
function checkWork($obj){
if($obj instanceof Work){ //定义方法判断对象是否实现某个接口
$obj->worker('coding');
}else{
echo "The programmer is playing basketball.";
}
}
checkWork($coding);
checkWork($holiday);
接口的继承
interface Ainter
{
public function func();
}
interface Binter extends Ainter
{
public function test();
}
class MyClass implements Binter
{
public function test(){
}
}
一个类实现多个接口
interface Ainter
{
public function func1();
}
interface Binter
{
public function func2();
}
class MyClass implements Ainter,Binter
{
public function func1(){
}
public function func2(){
}
}
多态呢,到这里就自然明白了,只要对象实现了某个接口,就直接可以通过对象调用接口的所有方法,接口实现的类方法有很多,这种现象就称为多态,相同的代码传入的对象不一样,所以具体实现方式也不一样,这就是多态的真正含义。
发表评论