关键词搜索

源码搜索 ×
×

《PHP 7从零基础到项目实战》学习笔记8——类与对象

发布2020-06-11浏览357次

详情内容

1. 什么是类

1.1 类的声明与实例化

<?php
/**
 * 类在使用前需要声明,声明一个类使用关键字class
 * Class conn
 */
// 声明一个数据库连接类
class conn
{
    private $dbtype = 'mysql'; // 数据库类型
    private $host = '127.0.0.1'; // 数据库服务器IP
    private $username = 'root'; // 用户名
    private $password = '123456'; // 密码
    private $pre = 'tb_'; // 数据库表前缀
    // 插入数据
    public function insert(){}
    // 更新数据
    public function update(){}
    // 删除数据
    public function delete(){}
    // 查询数据
    public function select(){}
}

// 实例化
$connObj = new conn();
var_dump($connObj);
?>
    object(conn)#1 (5) {
      ["dbtype":"conn":private]=>
      string(5) "mysql"
      ["host":"conn":private]=>
      string(9) "127.0.0.1"
      ["username":"conn":private]=>
      string(4) "root"
      ["password":"conn":private]=>
      string(6) "123456"
      ["pre":"conn":private]=>
      string(3) "tb_"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.2 访问类中的成员

    <?php
    
    class conn2
    {
        public $dbtype = 'mysql';
    
        private $pre = 'tb_';
    
        public function test() {
            echo 'test';
        }
    
        public function test2() {
            echo $this->getPre();
        }
    
        public function getPre() {
            echo $this->pre;
        }
    }
    // 实例化conn2
    $obj = new conn2();
    // 可使用“->”访问类中的成员
    $obj->test(); // test
    echo "\n";
    echo $obj->dbtype, "\n"; // mysql
    
    /**
     * 在对象方法执行的时候会自动定义一个$thiis的特殊变量,表示对象本身的引用。
     * 通过$this->形式可以引用该对象的方法和属性,其作用是完成对象内部成员之间的访问。
     */
    $obj->test2(); // tb_
    ?>
    
      28
    • 29
    • 30
    • 31
    • 32
    • 33

    访问对象的成员有时还可以使用“::”符号。使用该符号一般有以下几种情况:

    • parent:: 父类成员,这种形式的访问可调用父类的成员变量常量和方法。
    • self:: 自身成员,这种形式的访问可调用当前类中的静态成员和变量
    • 类名::成员,这种形式的访问可调用类中的变量常量和方法。
    <?php
    
    class conn3
    {
        public $dbtype = 'mysql';
    
        // 在类中使用const定义常量HOST
        const HOST = '127.0.0.1';
    
        public function test() {
            echo "test", "\n";
        }
    
        public function test1() {
            echo self::HOST; // self访问常量HOST
            self::getDbtype(); // self访问静态方法getDbtype()
        }
    
        // 使用static修饰的方法称为静态方法
        public static function getDbtype() {
            echo "mysql", "\n";
        }
    }
    
    // 类对象实例化
    $obj = new conn3();
    $obj->test1(); // 127.0.0.1mysql
    // 没有实例化类,使用“::”访问类中的方法
    conn3::test(); // test
    conn3::getDbtype(); // mysql
    
    class conn4 extends conn3
    {
        public function testPrint() {
            echo parent::test1();
        }
    }
    $conn4 = new conn4();
    $conn4->testPrint(); // 127.0.0.1mysql
    ?>
    
      28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    1.3 静态属性和静态方法

    在PHP中,通过static关键词修饰的成员属性和方法称为静态属性和静态方法。静态属性和静态方法可在不被实例化的情况下直接使用。

    1. 静态属性

      静态属性属于类本身,而不属于任何实例。静态属性使用static关键词定义,

      • 在类外部使用“类名::静态属性名”的方式访问
      • 在类内部可使用“self::静态属性名”的方式访问。
    <?php
    
    
    class myClass
    {
        static $staticVal = 0;
        function getStatic() {
            // self访问静态属性
            echo self::$staticVal;
            self::$staticVal++;
        }
    }
    echo myClass::$staticVal; // 0
    $obj = new myClass();
    $obj->getStatic(); // 0
    echo myClass::$staticVal; // 1
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    1. 静态方法

    与静态属性相似,使用static修饰的方法称为静态方法,也可在不被实例化的情况下使用,其属于类而不是被限制到任何一个特定的对象实例。因此,$this在静态方法中不可使用,但可在对象实例中通过“$this->静态方法名”的形式调用静态方法,在类内部需要使用“self::静态方法名”的形式访问。

    <?php
    
    
    class myClass2
    {
        static $staticVal = 0;
    
        public $val = 100;
    
        static function getStaticVal() {
            echo self::$staticVal;
        }
    
        static function changeStaticVal() {
            self::$staticVal--;
            echo self::$staticVal;
        }
    
        function change() {
            // 在类内部使用$this调用静态方法
            $this->changeStaticVal();
        }
    }
    
    myClass2::getStaticVal(); // 0
    
    myClass2::changeStaticVal(); // -1
    
    $obj = new myClass2();
    $obj->change(); // -2
    ?>
    
      28
    • 29
    • 30
    • 31

    1.4 构造方法和析构方法

    构造方法是在创建对象时自动调用的方法,析构方法是在对象销毁时自动调用的方法。

    1. 构造方法

    构造方法常用的场景是在创建对象时用来给变量赋值,构造方法使用“__construct”定义。

    <?php
    
    
    class person
    {
        public $name;
        public $age;
        public $gender;
        function __construct($name, $age, $gender)
        {
            $this->name = $name;
            $this->age = $age;
            $this->gender = $gender;
        }
    
        function get($key) {
            return $this->$key;
        }
    }
    
    $test_1 = new person('张三', 18, '男');
    echo $test_1->get('name'); // 张三
    $test_2 = new person('李四', 16, '女');
    echo $test_2->get('gender'); // 女
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    1. 析构方法

    析构方法是在对象被销毁前自动执行的方法。使用“__destruct”定义。

    在PHP中有一种垃圾回收机制,可自动清除不再使用的对象,释放内存。析构方法在垃圾回收程序执行之前被执行。

    <?php
    
    class person
    {
        public $name;
        public $age;
        public $gender;
        function __construct($name, $age, $gender)
        {
            $this->name = $name;
            $this->age = $age;
            $this->gender = $gender;
        }
    
        function get($key) {
            return $this->$key;
        }
    
        function __destruct() {
            echo "execute automatically before destroy", "\n";
    }
    }
    
    $test_1 = new person('张三', 18, '男');
    echo $test_1->get('name'), "\n"; // 张三
    $test_2 = new person('李四', 16, '女');
    echo $test_2->get('gender'), "\n"; // 女
    ?>
    
      28
    张三
    女
    execute automatically before destroy
    execute automatically before destroy
    
    • 1
    • 2
    • 3
    • 4

    2. 封装和继承

    2.1 封装

    可使用public、protected、private来修饰对象的属性和方法。使用不同修饰符的属性和方法,其可被访问的权限也不同:

    • 使用public修饰的属性和方法可在任何地方调用
    • 如果在类中的属性和方法前面没有修饰符,则默认修饰符为public
    • 使用protected修饰的属性和方法可在本类和子类中被调用,在其他地方调用将会报错
    • 使用private修饰的属性和方法只能在本类中被访问
    <?php
    
    class person2
    {
        public $name;
        private $age;
        protected $weight;
    
        function __construct($name, $age, $weight)
        {
            $this->name = $name;
            $this->age = $age;
            $this->weight = $weight;
        }
    
        private function get($key) {
            return $this->$key;
        }
    }
    
    class personB extends person2{
        function key($key) {
            return $this->$key;
        }
    }
    
    $obj = new person2('Tom', 22, '60kg');
    echo $obj->name; // Tom
    // echo $obj->age;
    echo $obj->get('age');
    $son = new personB('Beta', 18, '55kg');
    echo $son->name; // Beta
    echo $son->key('weight'); // 55kg
    echo $son->key('age');
    ?>
    
      28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    <?php
    
    
    class person2
    {
        public $name;
        private $age;
        protected $weight;
    
        function __construct($name, $age, $weight)
        {
            $this->name = $name;
            $this->age = $age;
            $this->weight = $weight;
        }
    
        public function get($key)
        {
            return $this->$key;
        }
    }
    
    class personB extends person2
    {
        function key($key)
        {
            return $this->$key;
        }
    }
    
    $obj = new person2('Tom', 22, '60kg');
    echo $obj->name; // Tom
    // echo $obj->age;
    echo $obj->get('age'); // 2
    echo $obj->get('weight'); // 60kg
    $son = new personB('Beta', 18, '55kg');
    echo $son->name; // Beta
    echo $son->key('weight'); // 55kg
    // echo $son->key('age'); // 访问不到age
    echo $son->get('age'); // 18
    ?>
    
      28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    2.2 继承特性

    把一个类作为公共基类(父类),其他的类继承自这个基类,则其它类中都具有这个基类的属性和方法,其他类也可以各自额外定义自己不同的属性和方法。

    • 类的继承使用关键词“extends”
    • 在子类中可以使用parent访问父类的方法
    • 在子类中可重写父类的方法
    <?php
    
    
    class student
    {
        public $name;
        private $age;
        protected $weight;
    
        /**
         * student constructor.
         * @param $name
         * @param $age
         * @param $weight
         */
        public function __construct($name, $age, $weight)
        {
            $this->name = $name;
            $this->age = $age;
            $this->weight = $weight;
        }
    
        function like() {
            echo "I like study.";
        }
    
        function age() {
            echo "I'm $this->name, $this->age years old this year.";
        }
    
        protected function get($key) {
            return $this->$key;
        }
    
        function set($key, $value) {
            $this->$key = $value;
        }
    }
    
    class person extends student {
    
        // 重写父类方法
        function get($key)
        {
            echo $this->$key;
        }
    
        function what() {
            parent::like(); // 子类中访问父类方法
        }
    
        function getAge() {
            $this->age(); // 调用继承自父类的方法
        }
    }
    // 使用继承自父类的__construct方法初始化实例
    $obj = new person('张三', 18, '120kg');
    $obj->get('name'); // 张三
    $obj->get('weight'); // 120kg
    $obj->what(); // I like study.
    $obj->set('name', '李四');
    $obj->getAge(); // I'm 李四, 18 years old this year.
    ?>
    
      28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    2.3 通过继承实现多态

    多态通过继承复用代码而实现,可编写出健壮可扩展的代码,减少流程控制语句(if else)的使用。

    <?php
    
    class animal
    {
        function skill() {
            echo "This function will be rewrite in the children.";
        }
    }
    
    class fish extends animal{
        function skill()
        {
            echo "I can swim!";
        }
    }
    
    class dog extends animal{
       function skill()
       {
           echo "I can run!";
       }
    }
    
    function test($obj) {
        $obj->skill();
    }
    
    test(new fish()); // I can swim!
    test(new dog()); // I can run!
    ?>
    
      28
    • 29
    • 30

    往期文章:

    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载