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 相关文章推荐
基于mysql的论坛(7)
Oct 09 PHP
php 高效率写法 推荐
Feb 21 PHP
通用PHP动态生成静态HTML网页的代码
Mar 04 PHP
一个不易被发现的PHP后门代码解析
Jul 05 PHP
php中base64_decode与base64_encode加密解密函数实例
Nov 24 PHP
PHP中开启gzip压缩的2种方法
Jan 31 PHP
php实现发送微信模板消息的方法
Mar 07 PHP
深入理解PHP内核(一)
Nov 10 PHP
PHP批量去除BOM头内容信息代码
Mar 11 PHP
thinkPHP5.0框架整体架构总览【应用,模块,MVC,驱动,行为,命名空间等】
Mar 25 PHP
CentOS7编译安装php7.1的教程详解
Apr 18 PHP
PHP常用函数之获取汉字首字母功能示例
Oct 21 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
PHP学习之PHP变量
2006/10/09 PHP
简单的移动设备检测PHP脚本代码
2011/02/19 PHP
简单的PHP多图上传小程序代码
2011/07/17 PHP
PHP实现对文本数据库的常用操作方法实例演示
2014/07/04 PHP
php通过Chianz.com获取IP地址与地区的方法
2015/01/14 PHP
PHP生成唯一ID之SnowFlake算法
2016/12/17 PHP
使用PHPExcel实现数据批量导出为excel表格的方法(必看)
2017/06/09 PHP
PHP中类型转换 ,常量,系统常量,魔术常量的详解
2017/10/26 PHP
jQuery 方法大全方便学习参考
2010/02/25 Javascript
js 多种变量定义(对象直接量,数组直接量和函数直接量)
2010/05/24 Javascript
理解Javascript_10_对象模型
2010/10/16 Javascript
javascript入门教程基础篇
2015/11/16 Javascript
jQuery 监控键盘一段时间没输入
2016/04/22 Javascript
js 动态添加元素(div、li、img等)及设置属性的方法
2016/07/19 Javascript
javascript中call,apply,bind函数用法示例
2016/12/19 Javascript
解决nodejs中使用http请求返回值为html时乱码的问题
2017/02/18 NodeJs
基于Bootstrap分页的实例讲解(必看篇)
2017/07/04 Javascript
jQuery实现浏览器之间跳转并传递参数功能【支持中文字符】
2018/03/28 jQuery
jquery ui 实现 tab标签功能示例【测试可用】
2019/07/25 jQuery
layui实现把数据表格时间戳转换为时间格式的例子
2019/09/12 Javascript
JS浏览器BOM常见操作实例详解
2020/04/27 Javascript
Python中操作文件之write()方法的使用教程
2015/05/25 Python
python利用Opencv实现人脸识别功能
2019/04/25 Python
Scrapy-Redis结合POST请求获取数据的方法示例
2019/05/07 Python
python获取Pandas列名的几种方法
2019/08/07 Python
pytorch神经网络之卷积层与全连接层参数的设置方法
2019/08/18 Python
Python调用Windows API函数编写录音机和音乐播放器功能
2020/01/05 Python
Python多线程通信queue队列用法实例分析
2020/03/24 Python
pycharm第三方库安装失败的问题及解决经验分享
2020/05/09 Python
军训的自我鉴定
2013/12/10 职场文书
迎八一活动主题
2014/01/31 职场文书
毕业生如何写自我鉴定
2014/03/15 职场文书
运动会加油稿20字
2014/11/15 职场文书
外科护士长工作总结
2015/08/12 职场文书
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
2021/04/25 Python
在Oracle表中进行关键词搜索的过程
2022/06/10 Oracle