PHP类的秘密(二)类常量

383 阅读1分钟

这是我参与更文挑战的第6天,活动详情查看: 更文挑战

书接上回, 说完成员变量和方法, 另一个类的另一个构成元素就是常量.

定义常量可以使用关键字 const, 在定义和使用常量的时候不需要使用 $ 符号。

常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。可以把在类中始终保持不变的值定义为常量。

常量可以通过对象进行访问, 也可以直接由::常量名,进行访问. 如果在类内部, 双引号前面可以是类名,$this, self, parent和static; 如果在类外部, 则只能是类名, 对象, 或成员方法.

我们通过一个例子, 看一下常量的访问:

class MyClass
{
const constant = 'constant value';    //定义常量并赋值;

function showConstant() 
    {
    echo  self::constant . "\n";      //在类内部,通过self访问方法所在类常量
    }
}
echo MyClass::constant . "\n";       //通过类名::在类外访问常量.
$classname = "MyClass";
echo $classname::constant . "\n"; // 通过字符串变量也可以访问
$class = new MyClass();
$class->showConstant();  //通过成员方法进行访问
echo $class::constant."\n"; // 通过对象进行访问

常量会被子类继承, 或者覆盖, 通过定义同名常量:

class AP
{
    const X=1;
    const Y=self::X;       //可以通过表达式定义常量,但表达式的值必须是常数;
    function output()
    {
    return $this::X;     //$this返回调用对象的类常量
    }
}
class BP extends AP
{
    const X=2;             //子类重写父类常量;
}

var_dump(BP::Y);             //int(1)输出继承父类的常量值;
$output=new BP;
var_dump($output->output());  //int(2)输出子类的常量值;

同样的,常量也有可见度public, private和protected:

  1. public可以在全局进行访问;
  2. private只能在本类内进行访问;
  3. protected可以被其自身以及其子类和父类访问;

我们来看一下可见度在常量上的效果:

   class MyC
    {
    public const MY_PUBLIC = 'public';    // 公有常量
    protected const MY_PROTECTED = 'protected';    // 受保护的常量
    private const MY_PRIVATE = 'private';    // 私有常量
    public function foo()
    {
    echo self::MY_PUBLIC;
    echo self::MY_PROTECTED;
    echo self::MY_PRIVATE;
    }
    }
    $myclass = new MyC();
    echo MyC::MY_PUBLIC;  //public 通过类名直接访问公共常量
    MyC::MY_PROTECTED; //报错, 受保护的常量无法在类外直接访问
    MyC::MY_PRIVATE; //报错, 私有常量无法在类外直接访问
    $myclass->foo(); //Public Protected Private, 调用成员方法,可以输出所在类的所有可见度的常量.
    

我们看一下对子类继承的影响:

class MyC2 extends MyC       //继承上一个类,那么父类的常量也可以通过子类访问
{
    function foo2()
    {
        echo self::MY_PUBLIC;
        echo self::MY_PROTECTED;
        echo self::MY_PRIVATE; // 报错Undefined constant, 父类私有常量,在子类不可见.
    }
}
$myclass2 = new MyC2; 
$myclass2->foo2(); //Public Protected,父类私有常量无法输出;

    

总结一下:

  1. 常量的赋值必须是常数.
  2. 常量的访问需要::双引号.
  3. 子类会继承父类的public和protected常量, 不会继承private常量.
  4. 子类可以改写父类的常量.
  5. 可见度限制对常量一样有效.

感谢阅读, 抛砖引玉, 如有不准确和错误的地方欢迎留言指正, 我会及时修正, 拜谢!

参考资料: www.php.net PHP官方文档