php 里氏替换,设计模式实例讲解 - 里氏替换

说明

里氏替换的简单理解

子类能够替代父类

我们来举一个例子来说明该原则。

首先,新建一个类 A

class A

{

public function fire() {}

}

类 B 为 A 的子类,并且重写了 fire 方法

class B extends A

{

public function fire() {}

}

根据里氏替换原则,子类必须能够替代父类。也就是说,虽然子类重写了父类的方法,但是在能够使用父类的场景里面,也一定要能够使用子类。例如,我们的定义一个 doSomething 方法,传入的是类 A

function doSomething(A $obj)

{

// do something with it.

}

根据里氏替换原则,doSomething 方法同样也应该适用于类 B

反面示例

父类

class VideoPlayer

{

public function play($file)

{

// 播放视频

}

}

子类

use Exception;

class AviVideoPlayer extends VideoPlayer

{

public function play($file)

{

if (pathinfo($file, PATHINFO_EXTENSION) != 'avi')

{

throw new Exception;

}

}

}

子类重写了 play 方法,且抛出了异常,而父类并没有抛出异常。很明显,子类并不能完全替代父类,因此,该例子违反了里氏原则。

面向接口编程

如何才能不违背里氏原则呢?正确的做法就是「面向接口编程」。

首先,用接口定义好方法

interface LessonRepositoryInterface

{

/**

* Fetch all records.

*

* @return array

*/

public function getAll();

}

接口作出了约定,子类的实现接口就必须遵从这些约定,一定程度上保证其能遵守里氏原则。

class FileLessonRepository implements LessonRepositoryInterface

{

public function getAll()

{

return [];

}

}

class DbLessonRepository implements LessonRepositoryInterface

{

public function getAll()

{

return Lesson::all()->toArray()

}

}

总结一下如何才能不违背里氏替换原则

子类抛出的异常必须与父类保持一致

子类的前置条件(调用某个方法需满足的条件)不得大于父类的前置条件

子类的后置条件(方法返回时必须达到的要求)不得小于父类的后置条件

本作品采用《CC 协议》,转载必须注明作者和本文链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值