第七章 PHP面向对象的程序设计
7.1 面向对象的介绍
类的实例化结果就是对象,对象的抽象就是类。类描述了一组有相同特性和相同行为的对象。
7.2 如何抽象一个类
7.2.1 类的声明
[一些修饰类的关键字] class 类名{
成员属性:
.....
成员方法:
.....
}
7.2.2 成员属性
在类中直接声明变量就称为成员属性,可以在类中声明多个变量,即对象中有多个成员属性。成员属性可以使用PHP中的标量类型和复合类型,所以也可以是其它类实例化的对象。
class Person {
var $no; //用var修饰,会被视为公有
public $name;
private $age;
static $sex;
}
7.2.3 成员方法
在类中直接声明的函数就称为成员方法,可以在类中声明多个函数,对象中就有多个成员方法。
class Person {
function say(){
//方法体
}
function eat($food){
//方法体
}
}
7.3 通过类实例化对象
7.3.1 实例化对象
$变量名 = new 类名称([参数列表]);
7.3.2 对象中成员的访问
$引用名 = new 类名称([参数列表]); //对象实例化
$引用名->成员属性 = 值; //对成员属性赋值
echo $引用名->成员属性; //获取成员属性的值
$引用名->成员方法; //访问对象中的成员方法
7.3.3 特殊的对象引用"$this"
"$this"
专门用来完成对象内部成员之间的访问
class Person {
public $name;
private $age;
static $sex;
function say(){
//在类中声明说话的方法,使用$this访问自己对象内部的成员属性
echo "我的名字:".$this->name.",我的性别:".$this->sex.",我的年龄:".$this->age."。<br>";
}
}
7.3.4 构造方法与析构方法
1.构造方法
在每个声明的类中都有一个称为构造方法的特殊成员方法,如果没有显式的声明它,类中都会默认存在一个没有参数列表并且内容为空的构造方法。如果显式的声明它,则类中的默认构造方法将不会存在。
当创建一个对象时,构造方法就会被自动调用一次,即每次使用关键字new来实例化对象时都会自动调用构造方法,不能主动通过对象的引用调用构造方法。所有通常使用构造方法执行一些有用的初始化任务。
function __construct([参数列表]){ //构造方法名称是以两个下划线开始的__construct()
//方法体。通常用来对成员属性进行初始化赋值
}
2.析构方法
PHP在对象被销毁前自动调用这个方法。析构方法允许在销毁一个对象之前执行一些特定操作,例如关闭文件,释放结果集等。
function __destruct(){ //析构方法名称是以两个下划线开始的__destruct()
//方法体,通常用来完成一些在对象销毁前的清理任务
}
7.4 封装性
- 封装性即把对象的全部成员属性和全部成员方法结合在一起,形成一个不可分割的独立单位(即对象)。
- 信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系
7.4.1 设置私有成员
在声明成员属性或成员方法时,使用private关键字修饰就实现了对成员的封装。
封装后的成员在对象的外部不能被访问,但在对象内部的成员方法中可以访问到自己对象内部被封装的成员属性和方法。
7.4.2 私有成员的访问
在对象中声明一个访问私有属性的方法,再把这个方法铜鼓public关键字设置为共有的访问权限。
7.4.3 __set()和__get()方法
PHP中有很多预定的方法,这些方法都是由两个下划线开始的。如果要使用这些方法,方法体中的内容需要用户自己按需求编写。使用时不需要用户直接调用,而是在特定的情况下自动被调用。
1.__set()
__set()控制对象外部只能为私有成员属性赋值,不能获取私有属性的值,声明格式如下:
void __set(string name,mixed value)
class Person{
private $sex;
function __set($propertyName,$propertyValue){
if($propertyName == "sex"){
if(!($propertyValue == "男"||$propertyValue=="女"))
return;
}
$this->$propertyName = $propertyValue;
}
}
$person = new Person;
person->sex = "男"; //调用了__set()方法,赋值成功
2.__get()
在对象的外部获取私有属性的值时,会自动调用此方法,返回私有属性的值
mixed __get(string name)
class Person{
private $sex = "男";
function __get($propertyName){
return $this->$propertyName;
}
}
$person = new Person;
echo person->sex; //调用了__get()方法,赋值成功
7.5 继承性
PHP采用单继承模式,一个类只能直接从另一个类中继承数据,但一个类可以有多个子类。
7.5.1 类继承的应用
使用“extends”继承
class Student extends Person
7.5.2 访问类型控制
类型的访问控制通过使用修饰符允许开发人员对类中成员的访问进行限制。PHP中有三个访问控制符
- public
- private
- protected
7.5.3 子类中重载父类的方法
通过在子类中定义与父类重名的函数来进行重载
如需要在子类中调用父类中被覆盖的方法,调用格式为“parent::方法名”
7.6 常见的关键字和魔术方法
7.6.1 final
- 使用final标识的类,不能被继承
- 在类中使用final标识的成员方法,在子类中不能被覆盖
7.6.2 static关键字
使用static关键字可以将类中的成员标识为静态的,既可以标识成员属性,也可以标识成员方法。
类的静态属性类似函数的全局变量。
类中的静态成员不需要对象而使用类名来直接访问
静态成员是属于类的,而不属于任何对象,所以不能用$this来引用,应使用self来引用
在静态方法中只能访问静态成员
类名::静态成员属性名 //在类的外部和成员方法中都可以使用这种方法访问静态成员属性
类名::静态成员方法名 //在类的外部和成员方法中都可以使用这种方法访问静态成员方法
self::静态成员属性名 //在类的外部和成员方法中都可以使用这种方法访问静态成员属性
self::静态成员方法名 //在类的外部和成员方法中都可以使用这种方法访问静态成员方法
7.6.3 const关键字
- const关键字用于将类中的成员属性定义为常量
- 常量通过在类名或在成员方法中使用self关键字访问,不能用对象访问
- 常量的属性是只读的,不能重新赋值
- const声明的常量名称前不要使用"$"符号,而且常量名称通常是大写的
7.6.4 克隆对象
- 使用“clone”关键字克隆对象
- 克隆以后,原本和副本两个对象完全独立,互不干扰
- __clone()方法不需要任何参数,该方法中自动包含$this对象的引用,是副本对象的引用
7.6.5 类中的通用方法__toString()
- 对象引用是一个指针,即存放对象在堆内存中的首地址的变量
- __toString()方法中一定要有一个字符串作为返回值
- 直接输出对象的引用时,会自动调用__toString()方法
7.6.6 __call()
- 调用对象中不存在的方法时就会自动调用__call()方法
function __call($functionName,$args)
7.6.7 自动加载类
- 当尝试使用一个PHP没有组织到的类时,它会寻找一个__autoload()的全局函数,如果存在这个函数,PHP就会用一个参数来调用它,参数即类的名称