PHP面向对象基础

1 关键的OOP概念
1.1 类
在OOP术语中,实体的性质和行为的具体定义成为类(class)。类用于表示要在应用程序中处理的实际事物。每个实体都包含一组性质和行为,在OOP中分别称为属性和方法。

1
2
3
4
5
6
7
8
9
10
11
12
class Employee{
private $name;
private $title;
protected $wage;

protected function clockIn(){
echo “Member $this->name clocked in at ”.date(“h:i:s”);
}
protected function clockOut(){
echo “Member $this->name clocked out at ”.date(“h:i:s”)
}
}

1.2 对象
类提供了一个基础,可以在此基础上创建实体的特定实例,这个特定实例称为对象(object)。
$employee = new Employee();

1.3 属性
1) 声明属性
一般包含作用域描述符(public 或 private)
2) 调用属性
属性要使用->操作符引用
3) 属性作用域
PHP支持5种属性作用域:public private protected final 和 static。
public
共同属性可以由相应的对象直接操作和访问。OOP中并不鼓励使用公共属性,是因为直接访问使得类无法很容易地完成某种数据验证。

private
private属性只能在定义属性的类中被访问。指定为私有的属性不能有实例化的对象直接访问,也不能由其子类使用。

protected
在本类和子类中可以可以访问和操作保护属性,这是私用属性所没有的特性。

final
为属性设置final作用域时,将阻止在子类中覆盖这个属性。

4) 用set()方法设置属性
设置方法(setter)负责隐藏属性的赋值实现,并在为类属性赋值之前验证类数据。形式为:
boolean
set([string property_name], [mixed value_to_assign])

5) 用get()方法获取属性
获取方法(getter)负责封装获得类变量所需的代码。形式为:
Boolean
get([string property_name])

6) 创建定制方法和设置方法
对管理复杂面向对象应用程序而已,set和get方法是不够的,可以考虑为每个私有属性创建两个方法:
class Employee{
private $name;
public function getName(){
return $this->name;
}
public function setName(){
$this->name = $name;
}
}

1.4 常量
在类中使用const类定义常量。

1.5 方法
1) 声明方法
2) 调用方法
3) 方法作用域
PHP支持6种方法作用域:public private protected abstracet final 和 static
public
公共方法可以在任何位置任何时间访问。
private
标记为private的方法只能在类内部使用,不能由实例化的对象调用,也不能由类的子类使用。
protected
标记为protected的类方法只能在该类及其子类中使用。
abstract
抽象方法只在父类中声明,子类中实现。只有声明为abstract的类可以声明抽象方法。
final
标记为final的方法可以防止被子类覆盖。
4) 类型提示
类型提示只用于对象和数组,整数和浮点数或字符串等无法使用。

2 构造函数和析构函数
2.1 构造函数
PHP通过名称__construct来识别构造函数。
1) 调用父类构造函数
PHP不会自动调用父类的构造函数,必须使用parent关键字显式地调用。

2.2 析构函数
析构函数名必须是__destruct(),脚本执行结束时,PHP会撤销内存中的所有对象。如果创建了不那么容易丢失的数据,并应当在对象撤销时撤销这些数据,为此就需要创建一个定制的析构函数。

3 静态类成员
创建一系列只属于类的属性或方法。在类内部,静态方法只能访问静态属性,并且需要使用self关键字来引用,在类外部应该直接使用类名来引用静态成员。

4 instanceof关键字
PHP5的另一个新成员是instanceof关键字。使用这个关键字可以确定一个对象时类的实例、类的子类还是实现了某个特定接口,并进行相应的操作。

5 辅助函数
1) 创建类别名
class_alias()函数会创建一个类别名,允许用多个名来引用一个类。PHP5.3新增。
2) 确定类是否存在
class_exists()返回判断类是否存在。
3) 确定对象上下文
get_class()函数返回object所属的类名。
4) 了解类方法
get_class_methods()函数返回一个数组,其中包含class_name类中定义的所有方法名。
5) 了解类属性
get_class_vars()函数返回一个关联数组,其中包含class_name类中定义的所有属性名及其相应的值。
6) 了解声明类
函数get_declared_classes()返回一个数组,其中包含当前执行脚本中定义的所有类名。
7) 了解对象属性
get_object_vars()函数返回一个关联数组,其中包含object可用的已定义属性及其相应的值。没有值的属性在关联数组中将被赋值为NULL。
8) 确定对象的父类
get_parent_class()函数返回object所属类的父类名。如果object类是基类,那么就返回该类的名称。
9) 确定接口是否存在
interface_exists()函数确定一个接口是否存在。
10) 确定对象类型
is_a(object object, string class_name)函数判断object是否是class_name的对象。PHP5-5.3中删除了此函数(大概是引入了instanceof关键字的缘故)
11) 确定对象的子类类型
is_subclass_of(mixed object, string class_name),判断object是否是class_name子类的对象
12) 确定方法是否存在
method_exists(object object, string method_name),判断object中method_name是否存在。

6 自动加载对象
将各个类放在单独的文件中是很常见的做法。PHP5中引入了自动加载对象的概念。自动加载运行定义特殊的__autoload函数,当引用未在脚本中定义的类时会自动调用这个函数。如下:

1
2
3
function __autoload($class){
require_once(“classes/$class.class.php”);
}

定义了这个函数后,将不再需要哪些require_once语句,因为当第一次调用一个类时,就会调用autoload并根据autoload中定义的命令加载类。

7 PHP不支持的高级OOP特性
方法重载 操作符重载 多重继承

8 对象克隆
PHP5中所有对象在默认情况下都被视为引用。因为所有对象都被视为引用而不是值,所以复制对象更为困难。
可以在对象前面加clone关键字来克隆对象,如object = clone targetObject;

可以在对象中定义一个__clone()方法来调整对象的克隆行为。

问题:如果对象中含有对其它对象的引用,clone如何进行?

9 继承
在PHP中,类继承通过extends关键字实现。

如果父类有构造函数,而且子类没有构造函数,那么在子类实例化时确实会执行父类构造函数。如果子类也有构造函数,那么当子类实例化时,不论父类是否有构造函数,只会执行子类的构造函数,如果希望执行父类的构造的函数,可以在子类的构造函数中使用parent引用服务器的构造函数。

10 接口
接口定义了实现某种服务的一般规范,声明了必需的函数和常量,但不指定如何实现。
当类通过implements关键字实现了接口后,接口中的所有方法都必须实现,如实现类没有实现所有方法,则必需声明为抽象类。(通常,在接口名前加上字母I来标识接口名称)

类可以extends某个类和implements一个或多个接口。

11 抽象类
抽象类是不能被实例化的类,只能作为有其它类继承的基类。声明抽象类必须在定义前面加上关键字abstract。

关于抽象类和接口:
如要创建一个模型将由一些紧密相关的对象采用,就可以使用抽象类。如果要创建一个由一些不相关对象采用的功能,就使用接口。
如果必须从多个来源继承行为,就使用接口。
如果知道所有类都会共享一个公共的行为实现,就使用抽象类,并在其中实现该行为。

12 命名空间
从PHP5.3开始,引入了命名空间概念。可以为各个类指定一个命名空间。比如打开类定义文件,在开头写入namespace 名字;即可。

比如:
namespace Com\Vfeelit\Lib;
…..
在实际使用这个类的代码中,可以使用:
use Com\Vfeelit\Lib as VF;
然后通过new VF\Clean()来调用类。

坚持原创技术分享,您的支持将鼓励我继续创作!