# 范围解析操作符

范围解析操作符，或者更简单地说是一对冒号，可以用于访问静态成员，类常量，还可以用于覆盖类中的属性和方法。当在类定义之外引用到这些项目时，要使用类名。也可以通过变量来引用类，但该变量的值不能是关键字（如 `self` ， `parent` 和 `static` ）。

```php
<?php

class Foo
{
    /**
     * Just a test constant.
     *
     * @var string
     */
    public const CONSTANT = 'FOO';
}

var_dump(Foo::CONSTANT);  // string(3) "FOO"

$foo = new Foo();
var_dump($foo::CONSTANT); // string(3) "FOO"

$foo = 'Foo';
var_dump($foo::CONSTANT); // string(3) "FOO"

$foo = 'Foo';
$foo = new $foo;
var_dump($foo::CONSTANT); // string(3) "FOO"

$foo = new Foo();
$foo = new $foo;
var_dump($foo::CONSTANT); // string(3) "FOO"

```

`self` ， `parent` 和 `static` 这三个特殊的关键字是用于在类定义的内部对其属性或方法进行访问的。

```php
<?php

class Foo
{
    /**
     * Just a test constant.
     *
     * @var string
     */
    public const CONSTANT = 'FOO';

    /**
     * Return the specified constant.
     *
     * @param  void
     * @return string
     */
    public function static(): string
    {
        return static::CONSTANT;
    }
}

class Bar extends Foo
{
    /**
     * Override the parent constant.
     *
     * @var string
     */
    public const CONSTANT = 'BAR';

    /**
     * Return the specified constant.
     *
     * @param  void
     * @return string
     */
    public function self(): string
    {
        return self::CONSTANT;
    }

    /**
     * Return the specified constant.
     *
     * @param  void
     * @return string
     */
    public function parent(): string
    {
        return parent::CONSTANT;
    }
}

$foo = new Foo();
$bar = new Bar();
var_dump($foo->static()); // string(3) "FOO"
var_dump($bar->self());   // string(3) "BAR"
var_dump($bar->parent()); // string(3) "FOO"
var_dump($bar->static()); // string(3) "BAR"

```

当一个子类覆盖其父类中的方法时， PHP 不会调用父类中已被覆盖的方法。是否调用父类的方法取决于子类。这种机制也作用于构造函数和析构函数，重载以及魔术方法。

```php
<?php

class Foo
{
    /**
     * Return a string.
     *
     * @param  void
     * @return string
     */
    public function method(): string
    {
        return 'foo';
    }
}

class Bar extends Foo
{
    /**
     * Override the parent method.
     *
     * @param  void
     * @return string
     */
    public function method(): string
    {
        return parent::method();
    }
}

$bar = new Bar();
var_dump($bar->method()); // string(3) "foo"

```

