【简介】
静态方法和属性:通过类而不是对象来访问数据和功能。
抽象类和接口:设计和实现分离。
错误处理:异常。
Final类和方法:限制继承。
拦截器方法:自动委托。
析构方法:对象销毁前的清理工作。
3. 高级特性
3.1 静态方法和属性
静态属性和静态方法可以通过类直接来访问。
静态属性和静态方法需要用 static 关键字来声明。
class StaticExample {
static public $aNum = 0;
static public function sayHello() {
print "hello";
}
}
静态方法可以访问静态的成员属性,但不能访问非静态的成员属性。
使用 :: (两个冒号)来访问静态方法或属性。
StaticExample::$aNum;
StaticExample::sayHello();
使用 self 关键字来访问当前类中的静态属性或静态方法,不能使用$this访问静态属性或方法。
class StaticExample {
static public $aNum = 0;
static public function showNum() {
print self::$aNum;
}
}
3.2 常量属性
1)常量属性使用 const 关键字来声明,用大写字母来命名。
class constExample {
const NUM = 1;
const STATUS = true;
}
2)不能将一个对象指派给常量。
3)和静态属性一样,通过类而不能通过对象来访问。
3.3 抽象类
1)抽象类不能被直接实例化。
2)抽象类中只定义子类需要的方法。
3)子类可以继承抽象类,并且通过实现其中的抽象方法,是抽象类具体化。
4)使用 abstract 关键字定义一个抽象类。
abstract class abstractExample {
private $name;
public function show() {
echo "hello";
}
}
5)抽象方法也用 abstract 关键字声明,其中不能有具体内容,即没有方法体。
abstract public function fun();
6)抽象类的每个子类都必须实现抽象类中的所有抽象方法,或者把它们自己也声明成抽象类。
7)新的实现方法的控制权限需要小于抽象方法。
3.4 接口
1)接口只能定义功能,而不能包含实现的内容。
2)使用 interface 关键字来声明接口。
3)接口可以包含属性和方法的声明,但方法的方法体必须为空。
interface InterfaceExample {
public $num;
public function fun();
}
4)任何实现接口的类都要实现接口中所定义的所有方法,否则该类必须声明为 abstract。
5)一个类使用 implements 关键字来时接口。
class ImplementsExample implements InterfaceExample {
public function fun(){
return 'hello';
}
}
6)一个类可以实现多个接口,但是只能继承一个父类。
class Zi extends Fu implements Interface1, Interface2 {}
3.5 延迟静态绑定:static 关键字
这项技术是在 PHP5.3时引进的,用于处理静态方法用作工厂方法(工厂方法是生成包含类的实例的一种方法),会出现的调用顺序问题。
例如以下的代码:
abstract class DomainObject {}
class User extends DomainObject {
public static function create() {
return new User();
}
}
class Document extends DomainObject {
public static function create() {
return new Document();
}
}
这段代码都能很好地实例出 User 对象和 Document 对象,但是存在代码的重复,两个create() 方法,如果能整合到父类 DomainObject 中去的话,代码就会简洁很多。
abstract class DomainObject {
public static function create() {
return new self();
}
}
class User extends DomainObject {}
class Document extends DomainObject {}
但是我们发现在调用的时候会报错:
User::create();
Document::create();
PHP Fatal error: Cannot instantiate abstract class DomainObject in ...
这是因为 self 解析的是定义这个 create() 方法的类 DomainObject,就相当于 new DomainObject(),实例了抽象类,所以报错了;而不是解析为调用 self 所在方法 create() 的类 Document。
这个问题解决的方法就是使用 static,它指的是被调用的类,而不是包含类。在本例中的意思是调用 Document::create() 将生成一个新的 Document 对象,而不是试图实例化一个 DomainObject 对象。
abstract class DomainObject {
public static function create() {
return new static();
}
}
class User extends DomainObject {}
class Document extends DomainObject {}
print_r(Document::create());
// Document Object ( )
static 还可用于调用静态方法。
3.6 错误处理
文件放错地方,数据库服务器未初始化,URL有变动,XML文件毁坏,权限设置得不对,超过了磁盘空间限制等,都会导致错误发生,因此,一个错误处理机制是十分有必要的。
异常(exception)是在 PHP5 时引入的,是从 PHP5 内置的 Exception 类(或其子类)实例化得到的特殊对象。
Exception 类型的对象用于存放和报告错误信息。
联合使用 Throw 关键字和 Exception 对象来抛出异常。
throw new Exception("something wrong!");
使用 try-catch 捕获异常。
try {
//...
} catch(Exception $e) {
throw $e;
}
3.7 Final 类和方法
final 关键字可以终止类的继承。
final 类不能有子类,final 方法不能被覆写。
final class FinalExample {}
class FinalTest extends FinalExample{}
报错:PHP Fatal Error:Class IllegalCheckout may not inherit from final class...