final 详解

Final 关键字

PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

<?php
    final class Foo
    {
        public function doFoo()
        {
            return "foo->doFoo";
            // do something useful and return a result
        }
    }

    final class FooDecorator
    {
        private $foo;

        public function __construct(Foo $foo)
        {
            $this->foo = $foo;
        }

        public function doFoo()
        {
              $result = $this->foo->doFoo();
              // ... customize result ...
              return $result;
        }
    }

    $o = new FooDecorator(new Foo());
    var_dump($o->doFoo());

?>

output:
    string(10) "foo->doFoo"

Note: 属性不能被定义为 final,只有类和方法才能被定义为 final。

类被定义成 final 是不能被继承的(当类定义成final的时候,方法这些默认就是final,所以可以不用final修饰)
方法定义成 final 是不能被覆盖的
final 关键字在PHP中不能用于类常量。使用关键词'const'
final 关键字也不能修饰变量

1)防止类继承
2)防止方法重写或重编方法在子类

消除紧密耦合、使用最终的方法来替换类常量

紧密耦合示例(使用常量不好):
<?php
    interface FooInterface
    {
    }

    class Foo implements FooInterface
    {
        const BAR = 1;

        public function __construct()
        {
        }
    }

    interface BazInterface
    {
        public function getFooBar();
    }

    // 这个类不能单独进行单元测试,因为实际的类Foo也必须被加载以获得Foo: BAR的值
    class Baz implements BazInterface
    {
        private $foo;

        public function __construct(FooInterface $foo)
        {
            $this->foo = $foo;
        }

        public function getFooBar()
        {
            return Foo::BAR;
        }

    }

    $foo = new Foo();
    $baz = new Baz($foo);
    $bar = $baz->getFooBar();
?>



松耦合示例(消除了常使用):

<?php
    interface FooInterface
    {
        public function bar();
    }

    class Foo implements FooInterface
    {
        public function __construct()
        {
        }

        final public function bar()
        {
            return 1;
        }
    }

    interface BazInterface
    {
        public function getFooBar();
    }

    // 可以单独测试这个类,因为类Foo不需要通过mock FooInterface和调用final bar方法来加载
    class Baz implements BazInterface
    {
        private $foo;

        public function __construct(FooInterface $foo)
        {
            $this->foo = $foo;
        }

        public function getFooBar()
        {
            return $this->foo->bar();
        }

    }

    $foo = new Foo();
    $baz = new Baz($foo);
    $bar = $baz->getFooBar();
?>

trait 属性

01、使用插件的类可以覆盖方法
02、不能覆盖属性
03、插件不能定义const 常量
<?php
    trait PropertiesTrait {
        public $same = true;
        public $different = false;
    }

    class PropertiesExample {
        use PropertiesTrait;
        public $same = 1; // 严厉的标准
        public $different = true; // 致命错误
    }
?>

要使用 trait 属性(类似于final) 只能如下

<?php
    trait PropertiesTrait {
        public $same = true;
        public $different = false;
        function asd(){
            echo 'asd<br/>';
        }   
    }

    class PropertiesExample {
        use PropertiesTrait;
        function asd(){
            echo "sss<br/>";
        }
    }
    $o = new PropertiesExample();
    $o->asd();
    var_dump($o->same); // 使用属性 
?>

final 正确的写法

<?php
    class PropertiesExample {
        // 正确的写法
        final protected function example() {
        }
        // 错误的
        protected final function example222() {
        }
    }
?>

猜你喜欢

转载自blog.csdn.net/qq_16142851/article/details/80533378