类的封装简单的概括就是“私有化”,具体来说,是通过访问修饰符private关键字,将类中不需要外部访问的属性和方法进行私有化处理,只能被这个类中的方法调用,而不能被外部或她的子类调用,即通过本类中提供的方法来访问本类中的私有属性。并且通过隐藏对象的属性和实现细节,仅对外提供公共的调用,控制在程序中属性的读取和修改的访问级别。

访问控制(可见性约束)

  1. public:公开的,默认都为public,任何地方可以访问,包括类的外部(就是实例化的对象)
  2. protected:受保护的,被其自身或者子类所访问
  3. private:私有的,只能被其定义所在的类里面访问
<?php
header('content-type:text/html;charset=utf-8;');
class MyClass
{
    public $a = 'public';
    protected $b = 'protected';
    private $c = 'private';
    public function test(){
        // 类自身调用
        echo $this->a;
        echo $this->b;
        echo $this->c;
    }
}
$obj = new MyClass();
// 类外以对象形式调用
echo $obj -> a;
//echo $obj -> b; //报错
//echo $obj -> c; //报错
$obj -> test(); //调用方法
?>

魔术方法

构造方法:在new一个对象时会自动执行的方法,PHP5可以在类中使用__construct()定义一个构造函数,具有构造函数的类,会在每次对象创建的时候调用该函数,因此常用来在对象创建的时候进行一些初始化工作。

<?php
header('content-type:text/html;charset=utf-8;');
class Construct
{
   function __construct(){
       print '构造函数被调用';
   }
}
$obj = new Construct(); //实例化的时候会自动调用构造函数__construct,这里会输出一个字符串
?>

析构方法:当对象被销毁的时候会自动执行的方法,使用__destruct()进行定义,析构函数指的是当某个对象的所有引用被删除,或者对象被显式的销毁时会执行的函数。

<?php
class Destruct
{
   function __construct() {
       print "构造函数被调用";
   }
   function __destruct() {
       print "析构函数被调用";
   }
}
$obj = new Destruct(); //实例化时会调用构造函数

//三种销毁方式
$obj = null; //销毁时会调用析构函数
unset($obj); //销毁时会调用析构函数
exit('结束掉'); //销毁时会调用析构函数
?>

静态属性和静态方法

static关键字来定义静态属性和方法

  1. 静态属性与方法可以在不实例化类的情况下调用
  2. 静态属性不允许对象使用->操作符调用,也就是静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
  3. 由于静态方法不需要通过对象也可调用,所以伪变量$this在静态方法中不可用

调用方法直接使用 类名:: 或者 self:: 进行调用

外部调用: 类名::属性名 类名::方法名

内部调用:类名/self::属性名 类名/self::方法名

<?php
header('content-type:text/html;charset=utf-8;');
class MyClass
{
    public static $color= 'red';
    public static function getSpeed() {
        echo self::$color;
        echo MyClass::$color;
        echo '<hr/>';
        MyClass::getsColor();
        echo '<hr/>';
        self::getsColor();
    }
    private static function getsColor() {
        echo 'The red is so colorful';
    }
}
MyClass::getSpeed();
echo MyClass::$color;

常量调用

关键字 const 可以把在类中始终保持不变的值定义为常量,常量必须是一个定值,且不能更改。

<?php
header('content-type:text/html;charset=utf-8;');
class Car
{
    const YES = true;
    const NO = false;
    const ONE = 1;
    const TWO = self::ONE; //self::代表这个类的本身
}
echo Car::ONE;
?>

重载

PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的。当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。

属性的重载通过__set()、__get()、__isset()和__unset来分别实现对不存在属性的赋值、读取、判断属性是否设置、销毁属性。

方法的重载通过__call()和__callStaic()调用。

属性重载

__set($var, $val)方法用来为私有成员属性设置值的,在给不可访问属性赋值时,__set()会被调用

__get($var)方法用来获取私有成员属性值的,在取不可访问属性的值时,__get()会被调用

<?php
header('content-type:text/html;charset=utf-8;');
class Person
{
    public $name = '小芳';
    protected $age = 18;
    public function __get($var){ //$var指的是不可访问属性的名字
        if($var == 'age'){
            return $this->age;
        }else{
            return '女孩子年龄不要问';
        }
    }
    public function __set($var,$val){
        echo '触发了设置不可访问的属性'.$var.'值为'.$val;
        $this->$var = $val;
    }
}
$obj = new Person();
echo $obj->age;
$obj->age = 30;

__isset($var)方法,当对不可访问属性调用isset()或empty()时,__isset()会被调用

__unset($var)方法,当对不可访问属性调用unset()时,__unset()会被调用

<?php
header('content-type:text/html;charset=utf-8;');
class Person
{
    public $name = '小芳';
    protected $age = 18;
    public function __isset($var){
        echo '判断一个不可访问的属性是否存在'.$var;
    }
    public function __unset($var){
        echo '销毁一个不可访问的属性'.$var;
    }
}
$obj = new Person();
isset($obj->age);
unset($obj->age);

方法重载

当对象中调用一个不可访问方法时,__call($name,  $arg)方法会被调用。

在静态上下文中调用一个不可访问方法时,__callStaic()方法会被调用。

<?php
header('content-type:text/html;charset=utf-8;');
class MyClass
{
    protected function func($var){
        echo '这是一个不可访问方法';
        echo '参数是'.$var;
    }
    public function __call($name, $arg){ //$name方法名称 $arg参数
        echo '触发了不可访问的方法';
        var_dump($name);
        var_dump($arg);
    }
    protected static function func2(){
        echo '受保护的静态方法';
    }
    public static function __callStatic($name, $arg){
        echo '触发了不可访问的静态方法';
        var_dump($name);
        var_dump($arg);
    }
}
$obj = new MyClass();
$obj->func('aaa',123);
MyClass::func2(1,2,3,4);