【深入PHP 面向对象】读书笔记(二) - 高级特性

【简介】
静态方法和属性:通过类而不是对象来访问数据和功能。
抽象类和接口:设计和实现分离。
错误处理:异常。
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...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值