【学习笔记】《深入PHP - 面向对象、模式与实践》(第3版)——第4章 高级特性

时间:2022-09-18 17:25:47

第4章 高级特性

4.1 静态方法和属性

  1. 面向对象编程中的实际操作都是通过类的实例(而不是类本身)完成的。毕竟,类仅仅是对象的模板。
  2. 然而,我们不仅可以通过对象访问方法和属性,还可以通过类来访问它们。这样的方法和属性是“静态的”(static),必须用static关键字来声明。
  3. 静态方法是以类作为作用域的函数。静态方法不能访问这个类中的普通属性,因为那些属性属于一个对象,但可以访问静态属性。如果修改了一个静态属性,那么这个类的所有实例都能访问到这个新值。

4.2 常量属性

  1. 错误和状态标志经常需要被硬编码进类中。虽然它们是公共的、可静态访问的,但客户端代码不能改变它们。
  2. PHP5可以在类中定义常量属性。和全局常量一样,类常量一旦设置后就不能改变。常量属性用const关键字来声明。常量不像常规属性那样以美元符号开头。按照惯例,只能用大写字母来命名常量。
  3. 当需要在类的所有实例中都能访问某个属性,并且属性值无需改变时,应该使用常量。

4.3 抽象类

  1. 抽象类不能被直接实例化。
  2. 抽象类中只定义(或部分实现)子类需要的方法。
  3. 子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化。
  4. 用abstract关键字定义一个抽象类。
  5. 大多数情况下,抽象类至少包含一个抽象方法。
  6. 新的实现方法的访问控制不能比抽象方法的访问控制更严格。新的实现方法的参数个数应该和抽象方法的参数个数一样,重新生成对应的类型提示。

4.4 接口

  1. 抽象类提供了具体实现的标准,而接口(interface)则是纯粹的模板。
  2. 接口只能定义功能,而不包含实现的内容。
  3. 接口可用关键字interface来声明。
  4. 接口可以包含属性和方法声明,但是方法体为空。
  5. 任何实现接口的类都要实现接口中所定义的所有方法,否则该类必须声明为abstract。
  6. 一个类可以在声明中使用implements关键字来实现某个接口。

4.5 延迟静态绑定:static关键字

【学习笔记】《深入PHP - 面向对象、模式与实践》(第3版)——第4章 高级特性

  1. static类似于self,但它指的是被调用的类而不是包含类。

4.6 错误处理

异常

  1. 异常是从PHP5内置的Exception类(或其子类)实例化得到的特殊对象。
  2. Exception类型的对象用于存放和报告错误信息。
  3. Exception类的构造方法接受两个可选的参数:消息字符串和错误代码。

1.抛出异常

throw new Exception();
try{
}catch(Exception $e){
}

2.异常的子类化

  1. 如果要创建用户自定义的异常类,可以从Exception类继承。
  2. 有两个理由这么做;首先,可以扩展异常类的功能;其次,子类定义了新的异常类型,可以进行自己特有的错误处理。
  3. 当异常没有被客户端代码捕获时,异常将会再次抛出,客户的调用代码会优先捕获它。这样的过程会一再发生,直到异常被捕获或者不再抛出。如果异常到最后也没有被捕获,将会引发致命错误。所以,当抛出异常时,要强制要求客户端代码对它进行处理。

4.7 Final类和方法

  1. final关键字可以终止类的继承。final类不能有子类,final方法不能被覆写。
  2. final关键字应该放在其它修饰词之前。

4.8 使用拦截器

  1. PHP提供了内置的拦截器(interceptor)方法,它可以“拦截”发送到未定义方法和属性的消息,也被称为重载(overloading)。
    【学习笔记】《深入PHP - 面向对象、模式与实践》(第3版)——第4章 高级特性
  2. __call()方法对于实现委托也很有用。委托是指一个对象转发或者委托一个请求给另一个对象,被委托的一方替原先对象处理请求。
  3. 用__call()实现自动委托可以节省很多时间,但代码也会变得不太清晰,不易理解。对外界来说,你提供了一个动态的接口,没有办法进行反射(reflection)。
  4. 使用__call()委托使类和被委托类之间的交互可能比较模糊,因为不是用显式的继承关系或者参数类型提示。
  5. 拦截器方法非常有用,但在使用时要慎重考虑,而且最好附上文档,清楚地说明代码的细节。

4.9 析构方法

  1. 它只在对象被垃圾收集器收集前(即对象从内存中删除之前)自动调用。

4.10 使用__clone()复制对象

  1. 实现__clone()方法时,__clone是在复制得到的对象上运行的,而不是在原始对象上运行。
  2. 在复制对象属性时只复制引用,并不复制引用的对象。这会导致两个对象中的对象类型的属性指向同一个对象。附上解决方法:
    【学习笔记】《深入PHP - 面向对象、模式与实践》(第3版)——第4章 高级特性

4.11 定义对象的字符串值

  1. PHP5中引入的一个受Java启发的功能是__toString()方法。
  2. 通过实现自己的__toString()方法,你可以控制输出字符串的格式。
  3. __toString()方法应当返回一个字符串值。当把对象传递给print或echo时,会自动调用这个方法,并用方法的返回值来替代默认的输出内容。

4.12 回调、匿名函数和闭包

  1. 利用回调,你可以在运行时将与组件的核心任务没有直接关系的功能插入到组件中。
$func = function($args){
    echo $args;
};