PHP OPP机制和模式简介(抽象类、接口和契约式编程)


Posted in PHP onJune 09, 2014

1.抽象类

抽象类机制中总是要定义一个公共的基类,而将特定的细节留给继承者来实现。通过抽象概念,可以在开发项目中创建扩展性很好的架构。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。在类的声明中使用 abstract 修饰符就可以将某个类声明为抽象的。

1.1方法原型(prototype)

是指方法的定义中剔除了方法体之后的签名。它包括存取级别、函数关键字、函数名称和参数。他不包含({})或者括号内部的任何代码。例如下面的代码就是一个方法原型:

public function prototypeName($protoParam)

继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。

1.2关于抽象类

    某个类只要包含至少一个抽象方法就必须声明为抽象类
    声明为抽象的方法,在实现的时候必须包含相同的或者更低的访问级别。
    不能使用 new 关键字创建抽象类的实例。
    被生命为抽象的方法不能包含函数体。
    如果将扩展的类也声明为抽象类,在扩展抽象类时,可以不用实现所有的抽象方法。(如果某个类从抽象类继承,当它没有实现基类中所声明的所有抽象方法时,它就必须也被声明为抽象的。)

1.3使用抽象类

<?php
abstract class Car
{    
    abstract function getMaxSpeend();
}
class Roadster extends Car
{
    public $Speend;
    public function SetSpeend($speend = 0)
    {
        $this->Speend = $speend;
    }
    public function getMaxSpeend()
    {
        return $this->Speend;
    }
}
class Street
{
    public $Cars ;
    public $SpeendLimit ;
    function __construct( $speendLimit = 200)
    {
        $this -> SpeendLimit = $speendLimit;
        $this -> Cars = array();
    }
    protected function IsStreetLegal($car)
    {
        if ($car->getMaxSpeend() < $this -> SpeendLimit)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public function AddCar($car)
    {
        if($this->IsStreetLegal($car))
        {
            echo 'The Car was allowed on the road.';
            $this->Cars[] = $car;
        }
        else
        {
            echo 'The Car is too fast and was not allowed on the road.';
        }
    }
}
$Porsche911 = new Roadster();
$Porsche911->SetSpeend(340);
$FuWaiStreet = new Street(80);
$FuWaiStreet->AddCar($Porsche911);
/**
 *
 * @result
 * 
 * The Car is too fast and was not allowed on the road.[Finished in 0.1s]
 *
 */
?>

2.对象接口

使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。

接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。

接口中定义的所有方法都必须是公有,这是接口的特性。

接口是一种类似于类的结构,可用于声明实现类所必须声明的方法。例如,接口通常用来声明API,而不用定义如何实现这个API。

    大多数开发人员选择在接口名称前加上大写字母I作为前缀,以便在代码和生成的文档中将其与类区别开来。

2.1使用接口

和集成抽象类需要使用 extends 关键字不同的是,实现接口使用的是 implements 关键字。一个类可以实现多个接口,这时,我们需要用逗号将他们隔开。如果将某个类标记为实现了某个接口,但却没有实现这个借口的所有方法,将会抛出错误。

2.2使用接口的案例

<?php
abstract class Car
{    
    abstract function SetSpeend($speend = 0);
}
interface ISpeendInfo
{
    function GetMaxSpeend();
}
class Roadster extends Car implements ISpeendInfo
{
    public $Speend;
    public function SetSpeend($speend = 0)
    {
        $this->Speend = $speend;
    }
    public function getMaxSpeend()
    {
        return $this->Speend;
    }
}
class Street
{
    public $Cars ;
    public $SpeendLimit ;
    function __construct( $speendLimit = 200)
    {
        $this -> SpeendLimit = $speendLimit;
        $this -> Cars = array();
    }
    protected function IsStreetLegal($car)
    {
        if ($car->getMaxSpeend() < $this -> SpeendLimit)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public function AddCar($car)
    {
        if($this->IsStreetLegal($car))
        {
            echo 'The Car was allowed on the road.';
            $this->Cars[] = $car;
        }
        else
        {
            echo 'The Car is too fast and was not allowed on the road.';
        }
    }
}

$Porsche911 = new Roadster();
$Porsche911->SetSpeend(340);
$FuWaiStreet = new Street(80);
$FuWaiStreet->AddCar($Porsche911);
/**
 *
 * @result
 * 
 * The Car is too fast and was not allowed on the road.[Finished in 0.1s]
 *
 */
?>

3.instanceof 操作符

instanceof 操作符是PHP5中的一个比较操作符。他接受左右两边的参数,并返回一个boolean值。这个操作符是用来确定对象的某个实例是否为特定的类型,或者是否从某个类型继承,又或者实现类某个特定的接口。

echo $Porsche911 instanceof Car;
//result:1
echo $Porsche911 instanceof ISpeendInfo;
//result:1

4.契约式编程

契约式编程是指在编写类之前实现声明接口的一种编程实践。这种方法在保证类的封装性方面非常有用。使用契约式编程技术,我们可以在创建应用程序之前定义出视图实现的功能,这和建筑师在修建大楼之前先画好蓝图的做法非常相似。

5.总结

抽象类是使用 abstract 关键字声明的类。通过将某个类标记为抽象类,我们可以推迟实现所声明的方法。要将某个方法声明为抽象方法,只要去掉包含所有大括号的方法实体,将方法声明的代码行用分号结束即可。

抽象类不能直接实例化,他们必须被继承。

如果某个类从抽象类继承,当它没有实现基类中所声明的所有抽象方法时,它就必须也被声明为抽象的。

在接口中,我们可以声明没有方法体的方法原型,这点与抽象类很相似。他们之间的区别在于,接口不能声明任何具有方法体的方法;并且他们使用的语法也不一样。为了将揭开规则强制加到某个类上,我们需要使用implements关键字,而不是extends关键字。

有些情况下我们需要确定某个类是否是特定类的类型,或者是否实现了特定的接口。 instanceof 分成适合完成这个任务。instanceof 检查三件事情:实例是否是某个特定的类型,实例是否从某个特定的类型继承,实例或者他的任何祖先类是否实现类特定的接口。

某些语言具有从多个类继承的能力,这称为多重继承。PHP不支持多重继承。想法,他提供了为一个类声明多个接口的功能。

接口在声明类必须遵循的规则时非常有用。契约式编程技术使用这一功能来增强封装性,优化工作流。

PHP 相关文章推荐
用PHP和ACCESS写聊天室(二)
Oct 09 PHP
php 常用类整理
Dec 23 PHP
php 数组的合并、拆分、区别取值函数集
Feb 15 PHP
destoon实现调用当前栏目分类及子分类和三级分类的方法
Aug 21 PHP
PHP获取POST数据的几种方法汇总
Mar 03 PHP
PHP中把错误日志保存在系统日志中(Windows系统)
Jun 23 PHP
laravel学习教程之存取器
Jul 30 PHP
PHP CURL采集百度搜寻结果图片不显示问题的解决方法
Feb 03 PHP
thinkPHP5 tablib标签库自定义方法详解
May 10 PHP
Laravel框架中自定义模板指令总结
Dec 17 PHP
关于ThinkPHP中的异常处理详解
May 11 PHP
PDO::_construct讲解
Jan 27 PHP
PHP+ajaxfileupload+jcrop插件完美实现头像上传剪裁
Jun 09 #PHP
神盾加密解密教程(三)PHP 神盾解密工具
Jun 08 #PHP
神盾加密解密教程(二)PHP 神盾解密
Jun 08 #PHP
IIS6.0 开启Gzip方法及PHP Gzip函数分享
Jun 08 #PHP
PHP获取中英混合字符串长度的方法
Jun 07 #PHP
使用PHP破解防盗链图片的一个简单方法
Jun 07 #PHP
PHP防止post重复提交数据的简单例子
Jun 07 #PHP
You might like
全国FM电台频率大全 - 13 福建省
2020/03/11 无线电
《Re:从零开始的异世界生活》剧情体验,手游新作定名
2020/04/09 日漫
PHP编程与应用
2006/10/09 PHP
PHP date函数参数详解
2006/11/27 PHP
PHP中可以自动分割查询字符的Parse_str函数使用示例
2014/07/25 PHP
PHP的压缩函数实现:gzencode、gzdeflate和gzcompress的区别
2016/01/27 PHP
Laravel框架实现发送短信验证功能代码
2016/06/06 PHP
PHP实现支持CURL字符串证书传输的方法
2019/03/23 PHP
聊一聊JS中的prototype
2016/09/29 Javascript
Bootstrap实现导航栏的2种方式
2016/11/28 Javascript
JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法
2017/04/28 Javascript
在vue中封装可复用的组件方法
2018/03/01 Javascript
layer.close()关闭进度条和Iframe窗的方法
2018/08/17 Javascript
Node.js 使用request模块下载文件的实例
2018/09/05 Javascript
vue.js 双层嵌套for遍历的方法详解, 类似php foreach()
2018/09/07 Javascript
vue实现pdf导出解决生成canvas模糊等问题(推荐)
2018/10/18 Javascript
微信小程序实现的自定义分享功能示例
2019/02/12 Javascript
[52:12]FNATIC vs Infamous 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
使用scrapy实现爬网站例子和实现网络爬虫(蜘蛛)的步骤
2014/01/23 Python
Python的print用法示例
2014/02/11 Python
Python列表(list)、字典(dict)、字符串(string)基本操作小结
2014/11/28 Python
python处理xml文件的方法小结
2017/05/02 Python
python命令行解析之parse_known_args()函数和parse_args()使用区别介绍
2018/01/24 Python
python并发和异步编程实例
2018/11/15 Python
用python建立两个Y轴的XY曲线图方法
2019/07/08 Python
Python操作Excel工作簿的示例代码(\*.xlsx)
2020/03/23 Python
python代码区分大小写吗
2020/06/17 Python
python自动从arxiv下载paper的示例代码
2020/12/05 Python
毕业自我评价
2014/02/05 职场文书
优秀工会工作者事迹材料
2014/06/02 职场文书
先进党支部事迹材料
2014/12/24 职场文书
三年级学生期末评语
2014/12/26 职场文书
学校青年志愿者活动总结
2015/05/06 职场文书
《金钱的魔力》教学反思
2016/02/20 职场文书
pytorch实现线性回归以及多元回归
2021/04/11 Python
你真的了解PHP中的引用符号(&)吗
2021/05/12 PHP