6.3. 类的其它特性

未匹配的标注

持之以恒,方得始终!

类常量 const

class Math {
    const PI = 3.14;
}
echo Math::PI;

我们可以看到,直接用类去访问常量,可见,常量是属于类的。
为什么有类常量?其实还是为了更好的封装性,在现在的oop编程中,基本都是在类里面写代码的。

类静态方法 static

class Math {
    static function squared($input) {
        return $input*$input;
    }
}
echo Math::squared(8);

可以看到,静态方法也是直接用类去调用的,所以,它也是属于类的。
还有注意,它里面不能包含对象的引用,比如$this,因为类直接调用的情况下,它没有一个实例对象能引用的。

instanceof

  1. 可以检查一个对象,是否是某个类的实例。
  2. 可以检查一个对象的类,是否是从某个类继承来的。
  3. 可以检查一个对象的类,是否实现了某个接口。
class A {}
class B extends A {}
interface Displayable{}

$b = new B();

var_dump($b instanceof B); // bool(true) $b对象是否是类B的实例
var_dump($b instanceof A); // bool(true) $b对象的类,是否继承自类A
var_dump($b instanceof Displayable); // bool(false) $b对象的类,是否实现接口Displayable

函数中,对象参数

function check_hint(B $someclass) {
    ...
}

上面的函数,要求 $someclass 必须是 类B 的实例。或者继承了类B的类的实例。
如果传入类A的实例,则报错:

$a = new A();
check_hint($a); // Fatal error ...

如果是这样 function check_hint(A $someclass),要求类A的实例,我们给B类的实例,则不报错,因为B类继承了A类。

延迟静态绑定

子类中,重写父类的静态方法。
子类调用到了这个静态方法时,访问的是自己重写的。

class A {
    public static function who() {
        var_dump("111111");
        echo __CLASS__ . PHP_EOL;
    }

    public static function test() {
        static::who();
    }

}

class B extends A {
    // 重写了父类的静态方法
    public static function who() {
        var_dump("222222");
        echo __CLASS__ . PHP_EOL;
    }
}


A::test();
// string(6) "111111"
// A


B::test();
// string(6) "222222"
// B

克隆对象 clone

复制一个已有的对象

$c = clone $b; // 创建一个与$b一样的副本

__clone() 魔术方法,在被 clone 时,会自动调用,因此我们就可以用它做一些预处理的事情。比如修改属性。

抽象类,抽象方法

抽象类不能被实例化,同时,它的类方法也没有被实现,只是提供了一个类方法的声明。

abstract class A { // 抽象类
    abstract function operation($param1, $param2); // 抽象方法
}

主要作用其实可接口类差不多,相当于leader写好一个要实现的功能的类模板,手下的人写个类继承后,去重写里面的抽象方法。

abstract class A {
    abstract function add($n1, $n2);
}

class B extends A {
    public function add($n1, $n2) {
        return $n1 + $n2;
    }
}

$b = new B();
echo $b->add(1,11);

__call()

前面已经使用了很多魔术方法了,回顾一下 __get(), __set(), __construct(), __destruct(), __clone(),他们都是特定条件下,会自动触发。__call() 当然也是这样。

__call() 当调用一个类中没有的方法时,会自动执行它。

__call() 方法必须带有两个参数,第一个是调用的方法的名称,第二个是调用方法给的参数数组。

class A {
    public function __call($method, $param) {
        var_dump($method, $param);
        if ($method == 'display') {
            if (is_object($param[0])) {
                $this->displayObject($param[0]);
            } elseif (is_array($param[0])) {
                $this->displayArray($param[0]);
            } else {
                $this->displayScalar($param[0]);
            }
        }
    }

    protected function displayObject() {
        var_dump("displayObject is use...");
    }

    protected function displayArray() {
        var_dump("displayArray is use...");
    }

    protected function displayScalar() {
        var_dump("displayScalar is use...");
    }

}

$a = new A();
$a->display([1,2,3]);
$a->display('cat');

/* string(7) "display"
array(1) {
  [0]=>
  array(3) {
    [0]=>int(1)
    [1]=>int(2)
    [2]=>int(3)
  }
}
string(22) "displayArray is use..."
string(7) "display"
array(1) {
  [0]=>string(3) "cat"
}
string(23) "displayScalar is use..." */

上面代码的意思是,如果调用一个A类中没有的display()方法,则会触发__call()魔术方法,它里面根据请求的方法名称,再根据参数类型,决定最终要访问的方法是谁。

__autoload()

这是一个特殊函数,不是在类里面定义的。
它的作用是,在 new 一个对象时,如果这个类没有在当前脚本中声明,则会自动执行它。

一般的做法是,将需要的类声明文件包含进来。

function __autoload($classname) {
    include_once($classname . ".php");
}

类转为字符串 __toString()

如果在类中,实现了 __toString() 方法,当打印该类时,自动调用这个方法。


class A {

 public $testone;

 public $testwo;

 public  function __toString() {

 return var_export($this, true);

    }

}

$a = new A;

echo $a;

如有任何侵权行为,请通知我删除,谢谢大家!
个人邮箱:865460609@qq.com

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
Junwind
讨论数量: 0
发起讨论 只看当前版本


暂无话题~