2017-05-07 25 views
6

Tôi sử dụng PHP 7.1.0.Tại sao đổi tên phương thức không hoạt động trong các đặc điểm PHP?

giả sử chúng ta có một đặc điểm, chúng tôi sử dụng nó bên trong một lớp và đổi tên các phương pháp nhập khẩu:

trait T 
{ 
    public function A() { 
     echo "."; 
    } 
} 

class C 
{ 
    use T { 
     A as B; 
    } 
} 

$c = new C(); 
$c->B(); 
$c->A(); // Why does it work? 

Tại sao PHP vẫn cho phép tôi sử dụng tên phương pháp cũ (A trong trường hợp này)?

Nó thực sự là một nỗi đau bởi vì trong ví dụ phức tạp hơn bạn không thể dựa vào phương pháp đổi tên - và do đó bạn bất ngờ có thể nhận được "khai báo không tương thích" lỗi:

class BaseSrc 
{ 
} 

trait BaseTrait 
{ 
    public function init(BaseSrc $baseSrc) 
    { 
     echo "Init Base"; 
    } 
} 

class Base 
{ 
    use BaseTrait { 
     BaseTrait::init as initBase; 
    } 
} 

$base = new Base(); 
$base->initBase(new BaseSrc()); 
$base->init(new BaseSrc()); // WHY DOES IT WORK????? 

class MainSrc extends BaseSrc 
{ 
} 

trait MainTrait 
{ 
    use BaseTrait { 
     BaseTrait::init as initBase; 
    } 

    public function init(MainSrc $mainSrc) 
    { 
     $this->initBase($mainSrc); 
     echo "Init Main"; 
    } 
} 

// Warning: Declaration of MainTrait::init(MainSrc $mainSrc) should be compatible with Base::init(BaseSrc $baseSrc) 
class Main extends Base 
{ 
    use MainTrait; 
} 

Tôi nghĩ rằng, mã này nên làm việc. Vì tôi đổi tên thành init() thành initBase() trong lớp Base VÀ đã đổi tên giống nhau khi sử dụng BaseTrait bên trong MainTrait, tôi hy vọng rằng phương thức này (BaseTrait::init()) sẽ không xung đột với MainTrait::init(). Trong thực tế, PHP nói rằng tôi có các khai báo không tương thích. Lý do đằng sau việc đổi tên init as initBase không hoạt động - phương pháp init vẫn còn ở đó, trong lớp Base của tôi!

Có cách nào giải quyết vấn đề này mà không đổi tên BaseTrait :: init() thành một cái gì đó như BaseTrait :: initBase() ngay từ đầu (không chỉ trong câu lệnh use)?

Tôi có nên coi đây là lỗi PHP và báo cáo không? Có điều gì hợp lý đằng sau hành vi này không?

+1

những gì php.net viết về: 'Aliased_Talker sử dụng toán tử as để có thể sử dụng triển khai bigTalk của B trong một' ** bổ sung ** 'bí danh talk.' - http://php.net/manual /en/language.oop5.traits.php. Vì vậy, 'as' thêm bí danh nhưng không thay thế phương thức. Và sau đó: 'toán tử as có thể được sử dụng để thêm một bí danh vào một trong các phương thức. Lưu ý toán tử as không đổi tên phương thức và nó cũng không ảnh hưởng đến bất kỳ phương thức nào khác.' ' – splash58

+0

@ splash58 OK, cảm ơn. Tôi thấy: "như" không đổi tên, nó chỉ là "bí danh" (thành thật mà nói, tôi đã không đề cập đến ghi chú này trong khi đọc trang này về các đặc điểm). Có lý do nào đằng sau nó không? Tôi có nghĩa là, bất kỳ lợi thế của răng cưa thay vì đổi tên? Theo quan điểm của tôi, nó rất bất tiện. – Dm9

+0

Tôi nghĩ rằng 'thay thế' làm những gì bạn muốn. Liệu tôi có sai? Tôi không biết đặc điểm sâu như vậy – splash58

Trả lời

0

Như đã đề cập trong các nhận xét và để có đầy đủ; Từ PHP manual section on Traits:

The Aliased_Talker makes use of the as operator to be able to use B's bigTalk implementation under an additional alias talk.

Và sau đó:

The as operator can be used to add an alias to one of the methods. Note the as operator does not rename the method and it does not affect any other method either.

Vì vậy as thêm một bí danh nhưng không thay thế hoặc ảnh hưởng đến các phương pháp ban đầu trong bất kỳ cách nào. Đây là hành vi mong đợi.

Các vấn đề liên quan