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 相关文章推荐
在IIS上安装PHP4.0正式版
Oct 09 PHP
PHP session常见问题集锦及解决办法总结
Mar 18 PHP
php自动适应范围的分页代码
Aug 05 PHP
PHP Session_Regenerate_ID函数双释放内存破坏漏洞
Jan 27 PHP
如何给phpcms v9增加类似于phpcms 2008中的关键词表
Jul 01 PHP
又一个PHP实现的冒泡排序算法分享
Aug 21 PHP
php正则替换处理HTML页面的方法
Jun 17 PHP
php文件扩展名判断及获取文件扩展名的N种方法
Sep 12 PHP
php验证身份证号码正确性的函数
Jul 20 PHP
利用PHP命令行模式采集股票趋势信息
Aug 09 PHP
PHP 中常量的知识整理
Apr 14 PHP
php中Swoole的热更新实现代码实例
Mar 04 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自定义函数call_user_func和call_user_func_array详解
2011/07/14 PHP
关于mysql字符集设置了character_set_client=binary 在gbk情况下会出现表描述是乱码的情况
2013/01/06 PHP
php 批量生成html,txt文件的实现代码
2013/06/26 PHP
phpnow php探针环境检测代码
2014/11/04 PHP
php线性表的入栈与出栈实例分析
2015/06/12 PHP
php使用get_class_methods()函数获取分类的方法
2016/07/20 PHP
Javascript中自动切换焦点实现代码
2012/12/15 Javascript
简单的js表单验证函数
2013/10/28 Javascript
动态添加option及createElement使用示例
2014/01/26 Javascript
Javascript获取当前日期的农历日期代码
2014/10/08 Javascript
node.js中的fs.exists方法使用说明
2014/12/17 Javascript
JS动态修改图片的URL(src)的方法
2015/04/01 Javascript
JQuery实现鼠标移动图片显示描述层的方法
2015/06/25 Javascript
js图片卷帘门导航菜单特效代码分享
2015/09/10 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
2016/06/13 Javascript
详解Vue-cli代理解决跨域问题
2017/09/27 Javascript
基于Vuejs的搜索匹配功能实现方法
2018/03/03 Javascript
解决Vue-cli npm run build生产环境打包,本地不能打开的问题
2018/09/20 Javascript
BootStrap modal实现拖拽功能
2018/12/01 Javascript
ng-zorro-antd 入门初体验
2018/12/03 Javascript
通过实例了解js函数中参数的传递
2019/06/15 Javascript
15个简单的JS编码标准让你的代码更整洁(小结)
2020/07/16 Javascript
[36:16]完美世界DOTA2联赛PWL S3 access vs Rebirth 第一场 12.19
2020/12/24 DOTA
利用Python脚本在Nginx和uwsgi上部署MoinMoin的教程
2015/05/05 Python
python中Pycharm 输出中文或打印中文乱码现象的解决办法
2017/06/16 Python
Django进阶之CSRF的解决
2018/08/01 Python
python 获取url中的参数列表实例
2018/12/18 Python
Pycharm和Idea支持的vim插件的方法
2020/02/21 Python
菲律宾票务网站:StubHub菲律宾
2018/04/21 全球购物
通息工程毕业生自荐信
2013/10/16 职场文书
会计工作心得体会
2014/01/13 职场文书
单位作风建设剖析材料
2014/10/11 职场文书
党的群众路线教育实践活动总结大会主持词
2014/10/30 职场文书
乡镇一岗双责责任书
2015/01/29 职场文书
工资证明范本
2015/06/12 职场文书
css3实现的加载动画效果
2021/04/07 HTML / CSS