2016-03-28 18 views
7

Tôi có hai đặc điểm PHP rằng mỗi kế thừa từ các đặc điểm thứ 3 cùng:tránh va chạm tính trạng - use_once?

trait C { 
    public function smallTalk() { 
     echo 'c'; 
    } 
} 

trait A { 
    use C; 
    public function ac() { 
     echo 'a'.smallTalk(); 
    } 
} 

trait B { 
    use C; 
    public function bc() { 
     echo 'b'.smallTalk(); 
    } 
} 

Và tôi muốn sử dụng chúng cả trong một lớp học:

class D { 
    use A, B; 
    public function acbc() { 
     echo ac().bc(); 
    } 
} 

nhưng tôi vẫn gặp lỗi

Fatal error: Trait method smallTalk has not been applied, because there are collisions with other trait methods on D

Tôi biết use_once không phải là điều, nhưng tôi đang tìm kiếm cùng một chức năng mà require_once hoặc include_once cung cấp, nhưng đối với các đặc điểm. Ví dụ này được đơn giản hóa. C thực sự của tôi có rất nhiều phương pháp và được thừa kế bởi nhiều hơn 2 đặc điểm, vì vậy tôi không thực sự muốn lặp lại một chuỗi dài insteadof mỗi khi tôi sử dụng nhiều hơn 1 trong những đặc điểm này.

+0

phiên bản ngắn: Không, bằng tay xử lý va chạm là giá cho việc sử dụng đặc điểm này. – VolkerK

+0

Tôi nghi ngờ bạn đang lạm dụng các đặc điểm. Tôi chỉ sử dụng những đặc điểm như một phương sách cuối cùng. Câu trả lời này có một giải thích tốt về các lựa chọn thay thế (trong C++, nhưng chúng chủ yếu áp dụng cho bất kỳ ngôn ngữ OOP nào) http://stackoverflow.com/questions/406081/why-should-i-avoid-multiple-inheritance-in-c# answer-407928 – Pevara

Trả lời

0

Bạn cần đọc: Conflict Resolution

If two Traits insert a method with the same name, a fatal error is produced, if the conflict is not explicitly resolved.

To resolve naming conflicts between Traits used in the same class, the insteadof operator needs to be used to choose exactly one of the conflicting methods.

Since this only allows one to exclude methods, the as operator can be used to allow the inclusion of one of the conflicting methods under another name.

Ví dụ:

<?php 
trait A { 
    public function smallTalk() { 
     echo 'a'; 
    } 
    public function bigTalk() { 
     echo 'A'; 
    } 
} 

trait B { 
    public function smallTalk() { 
     echo 'b'; 
    } 
    public function bigTalk() { 
     echo 'B'; 
    } 
} 

class Talker { 
    use A, B { 
     B::smallTalk insteadof A; 
     A::bigTalk insteadof B; 
    } 
} 

class Aliased_Talker { 
    use A, B { 
     B::smallTalk insteadof A; 
     A::bigTalk insteadof B; 
     B::bigTalk as talk; 
    } 
} 
+0

Bạn đã đọc câu hỏi chưa? "C thật của tôi có rất nhiều phương pháp và được thừa kế bởi nhiều hơn 2 đặc điểm, vì vậy tôi không thực sự muốn phải lặp lại một chuỗi dài thay vì mỗi lần tôi sử dụng nhiều hơn 1 đặc điểm này." Tôi biết tôi có thể làm những gì bạn đang nói, nhưng tôi đã hỏi nếu có một giải pháp _better_. – wogsland

+1

Bạn sẽ không thể giải quyết xung đột bằng các phương tiện khác. Sử dụng đặc điểm + mở rộng. Nếu bạn muốn làm mọi thứ "đúng" - đừng cố gắng làm mọi thứ với sự trợ giúp của đặc điểm. Bạn có thể tạo một lớp C. D mở rộng từ C. Không có ví dụ thực tế - khó có thể nói kiến ​​trúc nào là đúng. Tôi khuyên bạn nên làm quen với SOLID. Nó có thể hỗ trợ trong việc lựa chọn kiến ​​trúc. –

+0

Được thăng hạng vì đây là câu trả lời đúng, ngay cả khi OP không thích câu trả lời đúng. – mopsyd