Rumah > Artikel > pembangunan bahagian belakang > PHP基础教程九之类与对象
类与对象
类的构成
对象的创建
PHP垃圾回收机制
$this讲解
PHP是一个面向对象的编程语言,那么什么是面向对象呢?我们为什么要面向对象呢?在我们的生活中有很多事物都是对象,比如一个杯子,一个盒子等,它们都有自己特有的特征,它们都是对象。而我们在开发中的开发也是面向对象编程的。对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象。我们使用面向对象编程可以使我们看问题能够看得全面,同时也有利于与数据的管理和维护,在PHP中面向对象可以分文两类,一类是模子,创造对象使用,一类是对象,使用模子创建的起来的,那么它们两个有什么关系呢?
类与对象:具有相同特性(数据元素)和行为(功能)的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。
也就是说把对象的功能和特征抽取出来,组成一个类,就好比把一个杯子的模型抽取出来,而我们可以根据这个模型(也就是类)去创建各种杯子(也就是对象)。
那么类是怎么定义的呢?对象又是怎么创建的?
<?php class Cat{ //定义一个猫类 public $name; //猫的名字 public $age;//猫的名字 public $color;//猫的颜色 //猫的构造方法 public function __construct(){ } public function sleep(){ echo '猫睡觉'; } public function eat(){ echo '猫吃饭'; } }
上面的就是一个类的基本结构,下面我们详细的讲解每个部分的意义。
class 是一个关键字,不能修改,表示这是一个类。
Cat是类名, 类名写法是大写字母开头,驼峰命名。
属性: 成员属性是类的一个组成部分,一般是基本数据类型(整数,字符串等),也可是复合类型(对象、数组) , 资源类型。比如我们前面定义猫类的public $age 就是成员属性。
可以说每个类都有属性,类的属性是一类的特征,比如说猫可以有名字,年龄,颜色等,这些猫类共有的特征。在类中这种特征我们称之为属性,当然我们也可以不定义属性。这个看自己的需求。
属性前面的public是一个权限修饰符,在后面会有讲解。
在上面的代码中可以看到在类中还有几个函数,它们和前面的函数是一样的,不过是前面多了一个权限控制符。也可以叫做成员方法,这些成员方法就是类中的行为动作,比如上面的猫类,有睡觉这个行为,也有吃饭这个行为,当然你可以自己写它有什么行为。
成员方法的语法:
访问修饰符 function 函数名(形式参数){ //函数体; //return 返回值; }
访问修饰符 , 有三种(public, protected, privte), 默认为public, 后面我们会详解
其它部就和我们学的函数一样了,包括调用机制
参数列表可以有多个,可以是任意类型
对于方法的返回值,这个可以看具体需求。
成员方法是定义在类中的,如果定义在类外就不是这个类的行为了。
上面的猫类中有一个方法,方法名是—__construct(),这是个构造函数,那么什么是构造函数?构造函数就是在创建对象的时候,进行初始化数据的方法,比如我们想在创建猫类对象的时候,直接把猫的名字、年龄和颜色给它,就可以使用到构造函数。
public function __construct($name,$age,$color){ $this-> name = $name; $this-> age = $age; $this-> color = $color; }
构造函数的语法是:
public function __construct(形式参数){ //函数体 }
对于构造函数的方法名__construct(),这个是一个魔术方法,在后面有介绍,其实构造函数还有一种写法,构造函数的方法名是类的名字:
public function Cat($name,$age,$color){ }
上面的构造方法定义方式也是正确的,但是推荐使用魔术方法的那一种(__construct()),以为这样当我们的类名发生改变的时候,不用修改。
注意PHP中类的名字不区分大小写,但是我们还是要按大小写来写。同时构造函数是没有返回值的。
构造函数需要注意的是:
在一个类中,只能有一个构造函数, 这个是强制要求
构造函数是系统自动调用的,我们不用自己调。
如果我们没有定义一个构造函数,系统会使用一个默认的构造函数,形式如下:public function
__construct(){},所以不管我们有没有定义构造函数,它都是有构造函数的。
上面的三种情况就是类中大致的内容,在后续我们还会降类中的其他情况。
在上面创建对象的类已经有了,那么怎么创建对象呢?
$cat = new Cat();
创建对象的语法是:
$对象名 = new 类名(参数1,参数2);
类名后面的括号里的参数是传递给类的构造函数的,如果构造函数没有参数,可以不写。
对象的命名规范和普通变量一样,使用驼峰法或者下划线法均可
new也是一个关键字,不能修改,表示新创建对象
我们创建对象的目的就是需要操作对象,而操作对象,就是操作对象里面的属性和方法。
在上面的类下面写如下代码:
//创建对象,传递三个参数到构造函数。 $cat = new Cat('小花',12,'black'); //通过对象来访问对象的属性 echo $cat -> name; echo '<br>'; echo $cat -> age; echo '<br>'; echo $cat -> color; echo '<br>'; $cat-> sleep(); $cat-> eat(); .....结果...... 小花 12 black 猫睡觉 猫吃饭
上面的对象通过->访问属性和方法。注意属性的前面没有$符号。
$对象名->属性名= 值; echo $对象名->属性名; '-> ' 称为对象运算符.
上面的就是对象的创建和最基本的应用
当我们把对象的值赋给另外一个变量是,是值传递还是引用传递?
//创建一个对象 $cat = new Cat('小花',12,'black'); $cat1 = $cat; // 把$cat这个对象赋给$cat1; $cat1 -> name = '小白';//利用$cat1这个对象修改对象的名字。 echo $cat1 -> name; //输出$cat1对象的名字。 echo '<br>'; echo $cat -> name; //输出$cat对象的名字。 .....结果...... 小白 小白
看到这里可能有点蒙,不是值传递吗?怎么修改一个对象的属性,另外一也变了?,
上面的代码当中 $cat1=$cat也是值传递,但是这个值是对象的引用(可以理解对象标识符),即每个包含对象的变量都持有对象的引(reference),而不是整个对象的拷贝。
在上面的图中可以看到,当$cat赋值给$cat1时,也就是对象标识符(#1)复制了一份,赋给$cat1,其实他们还是指向同一块数据区,所以只要其中一个修改了值,另外一个也会变。
我们使用完对象后,已经确定在以后不会使用这个对象了,这个时候我们可以手动的销毁对象,那么我们怎么让对象销毁呢?
当没有任何变量指向对象时,会销毁,因此我们可以把对象引用置为null
使用unset()函数来销毁对象。
//创建一个对象 $cat = new Cat('小花',12,'black'); $cat -> sleep(); unset($cat); $cat -> sleep(); .....结果..... 猫睡觉 Notice: Undefined variable: cat in D:\mywamp\Apache24\htdocs\zendstudio\yunsuanfu\object.php on line 27 Fatal error: Call to a member function sleep() on null in D:\mywamp\Apache24\htdocs\zendstudio\yunsuanfu\object.php on line 27
其实在一个文件运行完的时候,PHP会启动垃圾回收机制,自动的进行垃圾回收。这时候在里面创建的对象就自动销毁了,那么什么是PHP的垃圾回收机制?
垃圾回收,顾名思义,回收垃圾的,在程序中启动垃圾回收机制的时机:
在php中,当一个对象没有任何引用指向它的时候,就会成为一个垃圾对象,php将启动垃圾回收器将对象销毁。
当程序退出前,php也将启用垃圾回收器,销毁对象。
那么什么是垃圾回收机制?
垃圾回收机制是php5之后才有的,php5.3之前使用的垃圾回收机制是单纯的“引用计数”,也就是每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器+1;当变量引用撤掉后,计数器-1;当计数器=0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。但是PHP5.3开始,使用了新的垃圾回收机制,在引用计数基础上,实现了一种复杂的算法,来检测内存对象中引用环的存在(对象的相互引用),以避免内存泄漏。
在上面写类的构造函数的时候,可以看到在函数中使用到了$this,那么在面向对象中$this是什么?
$this是在类中使用的访问自身的一种机制。系统会给每个对象分配$this,代表当前对象。通俗的说就是在当前环境下,谁调用,$this就代表哪个对象。
<?php class Cat{ //定义一个猫类 public $name; //猫的名字 public $age;//猫的名字 public $color;//猫的颜色 //猫的定义方法 public function Cat($name,$age,$color){ $this-> name = $name; $this-> age = $age; $this-> color = $color; } public function sleep(){ echo '猫睡觉<br>'; } public function eat(){ echo '猫吃饭<br>'; } //输出猫的信息 public function info(){ echo '猫的名字是' . $this -> name . ' 年龄是' . $this-> age . ' 颜色是' . $this-> color; } } //创建一个对象 $cat = new Cat('小花',12,'black'); $cat -> info(); echo '<br>'; //创建另一个对象,传进不同的属性 $cat1 = new Cat('小白',6,'white'); $cat1 -> info(); .....结果..... 猫的名字是小花 年龄是12 颜色是black 猫的名字是小白 年龄是6 颜色是white
在上面的类中的info()函数中使用$this,不同的对象输出不同的结果,因为在不同的环境下,谁调用,$this就代表哪个对象。
在上面我们提到过,对象的销毁,其实在类中有一个方法,就是在对象销毁的时候由系统自动执行的。我们称之为析构函数。
public function __destruct(){ echo $this->name . '被销毁了<br>'; }
在PHP5中引入了析构函数的概念,析构函数会在某个对象的所有引用被删除(没有变量指向对象,要被销毁了),对象销毁前执行。
析构函数的主要作用是去释放对象分配的相关资源,比如数据库连接或打开的文件等。
它的语法是:
function __destruct(){ //函数体[释放资源,比如数据库连接,或者打开文件等等] }
析构函数也是系统自动调用的,我们不用自己调。但是当我们没有写析构函数的时候,系统不会执行析构函数。
<?php class Cat{ //定义一个猫类 public $name; //猫的名字 public $age;//猫的名字 public $color;//猫的颜色 //猫的定义方法 public function Cat($name,$age,$color){ $this-> name = $name; $this-> age = $age; $this-> color = $color; } public function sleep(){ echo '猫睡觉<br>'; } public function eat(){ echo '猫吃饭<br>'; } //输出猫的信息 public function info(){ echo '猫的名字是' . $this -> name . ' 年龄是' . $this-> age . ' 颜色是' . $this-> color; } public function __destruct(){ echo $this->name . '被销毁了<br>'; } } //创建一个对象 $cat = new Cat('小花',12,'black'); echo $cat -> name; //输出对象的名字 echo '<br>'; unset($cat); //销毁对象,系统自动调用析构函数。 .....结果...... 小花 小花被销毁了
当我们销毁对象$cat时,析构函数自动执行。
析构函数是在对象销毁前自动执行的,它没有返回值。切一个类中只能有一个析构函数。
析构函数是销毁对象创建的资源,不是销毁对象本身,对象本身是由垃圾回收机制销毁的。
当我们一个文件中创建了多个对象,在文件执行完毕,销毁对象的时候,是先创建的对象后销毁,后创建的对象,先销毁,这个原理和栈的原理很想,先进后出,后进先出。
通过上面对类和对象的讲解,我们可以知道类和对象的区别和联系。类是抽象的,代表着一类事物,如猫类。对象时具体的,代表一个具体事物。类是对象的模板,对象是类的一个个实例。同时类的基本构成要掌握。
以上就是PHP基础教程九之类与对象的内容,更多相关内容请关注PHP中文网(www.php.cn)!