11/08/2018, 20:48

Từ khóa private và final trong PHP

Private function trùng tên trong class cha - con Bản thân rất hay quên nên mình memo lại đây <?php class A { private function whoami() { echo 'A', PHP_EOL; } public function out() { $this->whoami(); } } class B extends A { private function whoami() ...

Private function trùng tên trong class cha - con

Bản thân rất hay quên nên mình memo lại đây

<?php
class A {
    private function whoami() {
        echo 'A', PHP_EOL;
    }

    public function out() {
        $this->whoami();
    }
}

class B extends A {
    private function whoami() {
        echo 'B', PHP_EOL;
    }
}

$a = new A;
$a->out();
$b = new B;
$b->out();

Khi chạy đoạn code này sẽ không hề có lỗi, mặc dù A và B là 2 class có 2 private function cùng tên là whoami. Kết quả sẽ trả lại 2 lần A, điều đó có nghĩa là $b->out(); gọi đến out() bên trong A, từ đó gọi đến whoami() bên trong A. Bây giờ mình sẽ thay đổi một chút

<?php
class A {
    private function whoami() {
        echo 'A', PHP_EOL;
    }

    public function out() {
        $this->whoami();
    }
}

class B extends A {
    private function whoami() {
        echo 'B', PHP_EOL;
    }

    public function out() {
        $this->whoami();
    }
}

$a = new A;
$a->out();
$b = new B;
$b->out();

Bây giờ kết quả sẽ là 1 lần A và 1 lần B. $b->out(); gọi đến out() bên trong B và lại gọi đến whoami() bên trong B. Như vậy có thể hiểu, với private function thì các class extend không nhìn thấy và không được coi là định nghĩa đè.

Để ngăn cản trường hợp trên, với mục địch cho code dễ đọc và dễ maintain hơn thì mình hay dùng từ khóa final

<?php
class A {
    final private function whoami() {
        echo 'A', PHP_EOL;
    }
}

class B extends A {
    private function whoami() {
        echo 'B', PHP_EOL;
    }
}

Đoạn trên đây khi chạy sẽ bắn ra lỗi và bắt buộc mình phải sửa tên hàm ngay.

PHP Fatal error:  Cannot override final method A::whoami() in /tmp/test.php on line 12
0