1. 类、属性和操作


1.1 类的结构

一个最简单的类定义如下:

class classname {
}

为了使类具有实用性,需要添加一些属性和操作。通过在类中使用关键词来声明变量,可以创建属性,这些关键词与变量的作用域相关:public、private和protected,例如:

class classname {public $attribute;
}

通过在类定义中声明函数,可以创建类的操作,例如:

class classname {public function operation() {}
}


1.2 构造函数与析构函数

大多数类都有构造函数与析构函数。当创建一个类时,它将调用构造函数,通常,这将执行一些初始化任务。与构造函数相对的是析构函数,析构函数允许在销毁一个类前执行一些操作或完成一些功能。构造函数名称必须是__construct(),析构函数名称必须是__destruct(),例如:

class classname {function __construct() {}function __destruct() {}
}


1.3 类的实例化

在声明一个类后,需要创建一个对象,这叫创建一个实例或实例化一个类。可以使用new来创建一个对象,例如:

class classname {function __construct() {}
}
$i = new classname();


1.4 使用类属性

在一个类中,可以访问一个特殊的指针$this,在类中通过一个操作设置或访问该变量时,可以使用$this->attribute来引用,例如:

class classname {public $attribute;function operation() {echo $this->attribute;}
}

是否可以在类的外部访问一个属性是由访问修饰符来确定。public的属性可以从类的外部直接访问,例如:

class classname {public $attribute;
}
$i = new classname();
$i->attribute = "Hello World";

可以通过__get()和__set()函数来实现对属性的访问,如果不直接访问一个类的属性而是编写访问函数,那么可以通过一段代码执行所有访问,例如:

class classname {public $attribute;function __get($name) {return $this->name;}function __set($name, $value) {$this->name = $value;}
}

如果使用$i->attribute=1,将间接调用__set()函数,__get()函数的工作原理类似。只有一个访问入口,就可以实现对要保存的数据进行检查,确保被保存的数据是有意义的数据。


1.5 访问控制

PHP提供了访问修饰符,它们可以控制属性和方法的可见性,通常放置在属性和方法声明之前。

1) 默认选项是public,意味着如果没有为一个属性或方法指定访问修饰符,它将是public。公有的属性和方法可以在类的内部和外部进行访问。

2) private访问修饰符意味着被标记的属性和方法只能在类的内部进行访问。

3) protected访问修饰符意味着被标记的属性或方法只能在类内部进行访问,它也存在于任何子类。


1.6 类操作的调用

与调用属性大体相同,可以使用同样方法调用类的操作,例如:

class classname {function operation() {}
}
$i = new classname();
$i->operation();


2. 继承和重载


2.1 实现继承

如果类是另一个类的子类,可以用关键词extends来指明其继承关系,例如:

class B extends A {
}

因为类B派生于类A,所有可以使用类A中声明的public或protected的操作和属性。作为A的子类,B具有与A一样的功能和数据。private指定的操作和属性不能被继承。

继承是单方向的,子类可以从父类或超类继承特性,但父类不能从子类继承特性。


2.2 重载

在子类中,再次声明相同的属性和操作也是有效的,我们可能需要在子类中给某个属性赋予一个与其超类属性不同的默认值,或者给某个操作赋予一个与其超类操作不同的功能,这就叫重载,例如:

class A {function operation() {}
}
class B extends A {function operation() {}
}

parent关键字允许调用父类操作的最初版本,但是PHP将使用当前类的属性值。


2.3 禁止继承

PHP提供了final关键字,当在一个函数声明前使用这个关键字时,这个函数将不能在任何子类中被重载,例如:

final class classname {
}


2.4 实现接口

如果需要实现多重继承功能,可以通过接口。接口的思想是指定一个实现了访接口的类必须实现的一系列函数,例如:

interface interfacename {function operation();
}
class classname implements interfacename {function operation() {}
}


3. 面向对象的高级功能


3.1 per-class常量

PHP提供了per-class常量的思想,这个常理可以在不需要初始化访类的情况下使用,例如:

class classname {const c = 1;
}
echo classname::c;


3.2 实现静态方法

PHP允许使用static关键字,该关键字适用于允许在未初始化类的情况下就可以调用的方法,等价于per-class常量的思想。在一个静态方法中,不能使用this关键字,因为可能会没有可以引用的对象实例。


3.3 检查类的类型

instanceof关键字允许检查一个对象的类型,可以检查一个对象是否是特定类的实例,是否是从某个类继承过来或是是否实现了某个接口。


3.4 延迟静态绑定

PHP5.3引入了延迟静态绑定,该特性允许在一个静态继承的上下文中对一个被调用类的引用,父类可以使用子类重载的静态方法。


3.5 克隆对象

PHP提供了clone关键字,该关键字允许复制一个已有的对象,例如:

$c = clone $i;

clone将创建与原有对象相同类的副本,而且具有相同的属性值。如果不需要克隆过来的默认行为,心须在基类中创建一个__clone()方法。当使用clone关键字时,该方法将被调用,在__clone()方法中,可以定义所需要的确切复制行为。


3.6 使用抽象类

PHP还提供了抽象类,这些类不能被实例化,同样类方法也没有实现,只是提供类方法的声明,例如:

abstract class A {abstract function operation($param);
}


3.7 使用__call()

__call()方法用来实现方法的重载,它必须带有两个参数,第一个包含了被调用的方法名称,被二个包含了传递给该方法的参数数组,例如:

public function __call($method, $p) {if ($method == 'test') {$this->display('test', $p[0], $p[1]);}
}


3.8 使用__autoload()

__autoload()不是一个类方法,而是个单独的函数,可以在任何类声明之外声明这个函数,如果实现了这个函数,它将在实例化一个还没有被声明的类时自动调用。

function __autoload($name) {include_once $name.'php';
}


3.9 将类转换成字符串

如果在实定义中实现了__string()函数,当尝试打印该类时,可以调用这个函数。