PHP基础教程九之类与对象

x33g5p2x  于2022-03-06 转载在 其他  
字(5.7k)|赞(0)|评价(0)|浏览(302)

本节讲解的内容

  • 类与对象
  • 类的构成
  • 对象的创建
  • 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,其实他们还是指向同一块数据区,所以只要其中一个修改了值,另外一个也会变。

对象的销毁

我们使用完对象后,已经确定在以后不会使用这个对象了,这个时候我们可以手动的销毁对象,那么我们怎么让对象销毁呢?

  1. 当没有任何变量指向对象时,会销毁,因此我们可以把对象引用置为null
  2. 使用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将启动垃圾回收器将对象销毁。
  • 当程序退出前,php也将启用垃圾回收器,销毁对象。

那么什么是垃圾回收机制?

垃圾回收机制是php5之后才有的,php5.3之前使用的垃圾回收机制是单纯的“引用计数”,也就是每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器+1;当变量引用撤掉后,计数器-1;当计数器=0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。但是PHP5.3开始,使用了新的垃圾回收机制,在引用计数基础上,实现了一种复杂的算法,来检测内存对象中引用环的存在(对象的相互引用),以避免内存泄漏。

$this说明

在上面写类的构造函数的时候,可以看到在函数中使用到了$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时,析构函数自动执行。

  • 析构函数是在对象销毁前自动执行的,它没有返回值。切一个类中只能有一个析构函数。
  • 析构函数是销毁对象创建的资源,不是销毁对象本身,对象本身是由垃圾回收机制销毁的。

当我们一个文件中创建了多个对象,在文件执行完毕,销毁对象的时候,是先创建的对象后销毁,后创建的对象,先销毁,这个原理和栈的原理很想,先进后出,后进先出。

总结

通过上面对类和对象的讲解,我们可以知道类和对象的区别和联系。类是抽象的,代表着一类事物,如猫类。对象时具体的,代表一个具体事物。类是对象的模板,对象是类的一个个实例。同时类的基本构成要掌握。

相关文章