《深入PHP:面向对象、模式与实践》(二)
第4章 高级特性
本章内容提要:
- 静态属性和方法:通过类而不是对象来访问数据和功能
- 抽象类和接口:设计和实现分离
- 错误处理:异常
- Final类和方法:限制继承
- 拦截器方法:自动委托
- 析构方法:对象销毁前的清理工作
- 克隆对象:创建对象的副本
- 把对象解析成字符串:创建摘要型方法
- 回调:用匿名函数为组件添加功能
4.1 静态属性和方法
静态属性和方法的声明:使用 static 关键字。
静态方法只能访问静态属性,不能访问普通属性。普通属性是属于对象的。
静态属性和方法的访问:使用 :: 来连接类名和静态元素。
一个类使用 parent 关键字来访问父类。在当前类(不是子类)访问静态元素,使用 self 关键字。在类外部,使用类名访问静态元素。
只有在使用 parent 关键字调用方法的时候,才能对一个非静态方法进行静态形式的调用。
静态元素的特性:
- 在任何地方都可用(假设你可以访问该类)
- 类的每个实例都可以访问类中定义的静态元素
- 不需要对象就能访问静态元素
书中介绍了一个静态方法,该方法接受原始数据,然后返回对象,就像“工厂”一样。
4.2 常量属性
常量属性使用 const 关键字来声明。常量属性不以美元符号开头,只能用大写字母来命名。
常量属性只包含基本数据类型的值。只能通过类而不能通过类的实例访问常量属性。引用常量属性时不需要用美元符号作为前导符。
当需要在类的所有实例中都能访问某个属性,并且属性值无需改变时,应该使用常量。
4.3 抽象类
用 abstract 关键字定义一个抽象类。可以创建抽象类的属性和方法。抽象类不能被实例化。
大多数情况下,抽象类至少包含一个抽象方法。抽象方法用 abstract 关键字声明,不能有具体内容,要以分号结束而不是方法体结束。
抽象类的每个子类都必须实现抽象类中的所有抽象方法,或者把它们自身也声明为抽象方法。
新的实现方法的访问控制不能比抽象方法的访问控制更严格。这些方法的调用方式也必须匹配,即类型和所需参数数量必须一致。
4.4 接口
抽象类提供了具体实现的标准,而接口则是纯粹的模板。
接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。
接口中定义的所有方法都必须是公有,这是接口的特性。
要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。
- 实现多个接口时,接口中的方法不能有重名。
- 接口也可以继承,通过使用 extends操作符。
- 类要实现接口,必须使用和接口中所定义的方法完全一致的方式。否则会导致致命错误。
接口中也可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖。
接口加上类型约束,提供了一种很好的方式来确保某个对象包含有某些方法。
本小节定义了一个 Chargeable 接口,再用 ShopProduct 类来实现,同时在其方法的参数中使用了类型约束。
4.5 延迟静态绑定:static 关键字
self:: 的限制:使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类。
延迟静态绑定:使用预留的 static 关键字,用于在继承范围内引用静态调用的类。
- 在非静态环境下,所调用的类即为该对象实例所属的类。由于 $this-> 会在同一作用范围内尝试调用私有方法,而 static:: 则可能给出不同结果。另一个区别是 static:: 只能用于静态属性。
- 延迟静态绑定的解析会一直到取得一个完全解析了的静态调用为止。另一方面,如果静态调用使用 parent:: 或者 self:: 将转发调用信息。
应用场景:可以为超类引入 组 的概念。
4.6 错误处理
本节举了一个简单的 conf 类的例子。这个类没有任何处理配置信息不存在或不可写的策略,只是假定了 XML 文档的格式正确并包含了需要的元素。这是很不明智的。
本节重点强调:应该把错误处理的责任集中放在类的内部,而不能依赖调用该类的程序员和外部代码。
4.7 异常
PHP5 引入了异常(exception)。
异常是从 PHP5 内置的 Exception 类(或其子类)实例化得到的特殊对象。
Exception 类的构造方法接受两个可选参数:消息字符串和错误代码。
1. 抛出异常
可以联合使用 throw 关键字和 Exception 对象来抛出异常。这会停止执行当前方法,并负责将错误返回给调用代码。书中重写了前面 conf 类的构造方法和 write() 方法。
如果调用可能会抛出异常的方法,那么可以把调用语句放在 try 子句中。try 子句由关键字 try 及其后面的括号组成。try 字句必须跟着至少一个 catch 子句才能处理错误。
2. 异常的子类化
通过继承 Exception 类,可以创建用户自定义的异常类。
定义多个 catch 子句时,只需一个 try 子句。调用哪一个 catch 子句取决于抛出异常的类型和参数中类的类型提示。
书中自定义了一个继承自 Exception 类的 XmlException 类、FileException 类、ConfException 类,并在 Conf 类中使用了这些自定义类。最后写一个 Runner 类来捕捉 Conf 类的构造方法可能抛出3个异常中的任意一个,该类使用了多个 catch 子句,并注意把 Exception 异常类型放在最后一个 catch 子句中。另外的一个技巧是,可以抛出包装了当前异常的新异常。
当异常没有被客户端代码捕获,异常会被再次抛出,客户的调用代码会优先捕获它。如果异常最后也没有被捕获,将会引发致命错误。所以当抛出异常时,要强制要求客户端代码对它进行处理。
4.7 Final 类和方法
final 类不能被继承,即不能有子类。final 方法不能被覆写。final 关键字应该放在其他修饰词(例如 protected 或 static)之前。
慎重使用 final 关键字。
4.8 使用拦截器
PHP 提供了内置的拦截器方法。
- __get( $property ):访问未定义的属性时被调用
- __set( $property, $value ):给未定义的属性赋值时被调用
- __isset( $property ):对未定义的属性调用 isset() 时被调用
- __unset( $property ):对未定义的属性调用 unset() 时被调用
- __call( $method, $arg_array ):调用未定义的方法时被调用
书中写了一个 Person 类,说明了如何使用拦截器方法。还写了一个 PersonWriter 类,用来说明 __call() 方法如何实现委托。过多地使用委托,会使代码变得不清晰。应慎重使用拦截器方法,并且最好附上说明文档。
4.9 析构方法
析构方法__destruct():只在对象被垃圾收集器收集前(即对象从内存中删除之前)自动调用。可以使用析构方法进行最后必要的清理操作。
书中给 Person 类添加了析构方法,并说明应该谨慎使用析构方法等魔术方法。
4.10 使用 __clone() 复制对象
在PHP中,对象的赋值和引用都是通过引用进行的。要获得一个对象的副本,PHP提供了clone关键字。clone使用“值复制”方式新生成一个对象。
在对象上调用clone时,可以通过实现__clone()方法来控制我们需要复制什么。当在一个对象上调用clone关键字时,其__clone()方法就会被自动调用。__clone()是在复制得到的对象上运行的,而不是在原始对象上运行的。
在复制对象属性时只复制引用,并不复制引用的对象。如果不希望对象属性在被复制之后被共享,那么可以显式得在__clone()方法中复制指向的对象。
4.11 定义对象的字符串值
通过实现__toString()方法,可以控制输出对象的字符串值的格式。__toString()方法应当返回一个字符串值。当把对象传递给print或echo时,会自动调用这个方法,并用方法的返回值来替代默认的输出内容。
4.12 回调、匿名函数和闭包
《深入PHP:面向对象、模式与实践》(二)的更多相关文章
- PHP面向对象编程 对象的基本概念 PHP面向对象的基本实践 PHP面向对象的高级实践 PHP面向对象的特殊实践
再次梳理一下面向对象编程的要点. 此文是以php为例,但思想是通用的. 总结的PHP面向对象编程笔记 对象的基本概念 对象的基本构成 对象包含两部分 一.对象的组成元素 是对象的数据模型,用于描述对象 ...
- 【Scrum】-NO.40.EBook.1.Scrum.1.001-【敏捷软件开发:原则、模式与实践】- Scrum
1.0.0 Summary Tittle:[Scrum]-NO.40.EBook.1.Scrum.1.001-[敏捷软件开发:原则.模式与实践]- Scrum Style:DesignPattern ...
- (转) 面向对象设计原则(二):开放-封闭原则(OCP)
原文:https://blog.csdn.net/tjiyu/article/details/57079927 面向对象设计原则(二):开放-封闭原则(OCP) 开放-封闭原则(Open-closed ...
- 敏捷软件开发:原则、模式与实践——第11章 DIP:依赖倒置原则
第11章 DIP:依赖倒置原则 DIP:依赖倒置原则: a.高层模块不应该依赖于低层模块.二者都应该依赖于抽象. b.抽象不应该依赖于细节.细节应该依赖于抽象. 11.1 层次化 下图展示了一个简单的 ...
- 敏捷软件开发:原则、模式与实践——第9章 OCP:开放-封闭原则
第9章 OCP:开放-封闭原则 软件实体(类.模块.函数等)应该是可以扩展的,但是不可修改. 9.1 OCP概述 遵循开放-封闭原则设计出的模块具有两个主要特征: (1)对于扩展是开放的(open f ...
- OOP 面向对象 七大原则 (二)
OOP 面向对象 七大原则 (二) 上一篇写到了前四个原则,这一篇继续~~ 接口隔离:客户端不应该依赖它不需要的接口:一个类对另一个类的依赖应该建立在最小的接口上. 又是一句大白话~就是说接口尽量 ...
- 手机淘宝轻店业务 Serverless 研发模式升级实践
一.前言 随着 Serverless 在业界各云平台落地,阿里内部 Serverless 研发平台.各种研发模式也在业务中逐步落地,如火如荼.在此契机下,淘系团队启动了轻店 Serverless 研发 ...
- ASP.NET MVC5 网站开发实践(二) Member区域–管理列表、回复及删除
本来想接着上次把这篇写完的,没想到后来工作的一些事落下了,放假了赶紧补上. 目录: ASP.NET MVC5 网站开发实践 - 概述 ASP.NET MVC5 网站开发实践(一) - 项目框架 ASP ...
- ASP.NET MVC5 网站开发实践(二) Member区域–我的咨询列表及添加咨询
上次把咨询的架构搭好了,现在分两次来完成咨询:1.用户部分,2管理部分.这次实现用户部分,包含两个功能,查看我的咨询和进行咨询. 目录: ASP.NET MVC5 网站开发实践 - 概述 ASP.NE ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 咨询管理的架构
咨询.留言.投诉等功能是网站应具备的基本功能,可以加强管理员与用户的交流,在上次完成文章部分后,这次开始做Member区域的咨询功能(留言.投诉都是咨询).咨询跟文章非常相似,而且内容更少.更简单. ...
随机推荐
- 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集
最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...
- JDK/Java里的设计模式
JDK/Java里的设计模式
- [BZOJ1143][CTSC2008]祭祀river(Dilworth定理+二分图匹配)
题意:给你一张n个点的DAG,最大化选择的点数,是点之间两两不可达. 要从Dilworth定理说起. Dilworth定理是定义在偏序集上的,也可以从图论的角度解释.偏序集中两个元素能比较大小,则在图 ...
- [xsy2962]作业
题意:$f_0=1-\dfrac1e,f_n=1-nf_{n-1}$,求$f_n(n\leq10000)$,保留四位小数 这题代码只有⑨行但是题解很神... 因为递推式中有乘法,所以直接按题目来推肯定 ...
- 【DFS】bzoj2079 [Poi2010]Guilds
对一棵树黑白染色一定符合题意. 图一定有生成树. 因此,仅有一个孤立节点的联通块不合题意. DFS. #include<cstdio> using namespace std; int n ...
- python3开发进阶-Django框架的Form表单系统和基本操作
阅读目录 什么是Form组件 常用字段和插件 自定义校验的方式 补充进阶 一.什么是Form组件 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标 ...
- 8.2(java学习笔记)反射
一.基础知识 对象是表示或封装一些数据,一个类被加载后JVM会创建一个对应该类的Class对象, 类的整个结构信息会被放在对应的对象中,通过这个对象我们可以获取改类的全部信息, 而这些操作称为反射. ...
- boost 1.57 vs2013 编译
启动vs2013中的命令行注意区分32/64, 进入boost目录, 再次运行 bootstrap.bat 编译: bjam.exe stage --toolset=msvc-12.0 --sta ...
- mysql获取分类数量
1.sql <select id="getTypeNum" resultType="TypeNum" > select count(*) as al ...
- oop 知识点回顾
1.抽象,封装 2.继承:连接类的层次模型,并且允许类的重用,提供共性的方法,从现有的类派生(方法的重写,扩展) 派生:新类继承了基类,那么新类就是派生类,适合更合适的需要 3.多态:允许不同的类的对 ...