2012-04-07 42 views
20

Tại sao chúng tôi không được phép mở rộng Đặc điểm với Lớp học bằng PHP?Mở rộng các đặc điểm với các lớp trong PHP?

Ví dụ:

Trait T { } 

Class C use T {} 
/* or */ 
Class C extends T {} 

Có bất kỳ cuộc xung đột tiềm năng cho các cú pháp như vậy? Tôi không nghĩ vậy.

+0

Làm thế nào 'Lớp C sẽ sử dụng T {} 'thể khác với những gì chúng ta đã có (ngoài cú pháp hơi khác nhau)? – Jon

+0

Cú pháp ngắn hơn khi tôi muốn mở rộng một số lớp từ một lớp cơ sở nhưng bằng cách sử dụng (các) đặc điểm. – Meglio

+1

@Meglio: Chỉ cần làm điều đó: 'Lớp C mở rộng Cơ sở {sử dụng T}'. – hakre

Trả lời

5

Chỉ có thể gia hạn các lớp học. Các đặc điểm là các lớp không phải là. Chúng có thể được sử dụng/bao gồm bởi các lớp nhưng không phải là các lớp. Nếu bạn nghĩ rằng một đặc điểm cần phải được mở rộng thì nó có thể là một lớp, có lẽ là một lớp trừu tượng, và không phải là một đặc điểm.

+0

Ý tưởng ở đây là cho cú pháp ngắn hơn, không phải cho cách để thực sự mở rộng các đặc điểm. – Meglio

+3

@Meglio: cú pháp không có độ dài, do đó không có cú pháp ngắn hơn. – hakre

+0

Ký hiệu ngắn hơn. – Meglio

31

Các PHP thủ quốc gia như sau:

đặc điểm là một cơ chế để tái sử dụng mã trong ngôn ngữ thừa kế duy nhất như PHP. Một Trait nhằm giảm bớt một số hạn chế của thừa kế đơn lẻ bằng cách cho phép một nhà phát triển sử dụng lại các phương thức một cách tự do trong một số lớp độc lập sống trong các phân cấp lớp khác nhau. Ngữ nghĩa của sự kết hợp các Đặc điểm và các lớp được định nghĩa theo cách làm giảm độ phức tạp và tránh các vấn đề điển hình liên quan đến đa thừa kế và Mixins.

Nếu bạn muốn mở rộng đặc điểm, thì có lẽ đó là một lớp học. Nếu bạn có một tập hợp các phương thức trong một lớp mà bạn muốn sử dụng trong các lớp khác, nhưng nó cảm thấy không thích hợp để mở rộng lớp (ví dụ: class Animal extends Vehicle), sau đó trong PHP 5.4 nó có thể hoạt động tốt như một đặc điểm.

Để trả lời câu hỏi trực tiếp hơn, bạn không 'mở rộng' một đặc điểm, nhưng bạn có thể tạo các đặc điểm tự sử dụng các đặc điểm khác. Theo hướng dẫn sử dụng PHP:

trait Hello { 
    public function sayHello() { 
     echo 'Hello '; 
    } 
} 

trait World { 
    public function sayWorld() { 
     echo 'World!'; 
    } 
} 

trait HelloWorld { 
    use Hello, World; 
} 

class MyHelloWorld { 
    use HelloWorld; 
} 

Bạn có thể xem đây là cách để duy trì các đặc điểm của mình trong các nhóm lôgic và giới thiệu một số mô đun.

Chỉnh sửa: đã thấy một số nhận xét, tôi nghĩ đáng lưu ý rằng việc sử dụng đặc điểm trong lớp cơ sở cũng có nghĩa là đặc điểm nằm trong bất kỳ lớp nào mở rộng nó và các chức năng của đặc điểm được ưu tiên hơn lớp cơ sở ' . Đặt nó trong lớp con sẽ chỉ đơn thuần làm cho các hàm của đặc điểm không có sẵn cho lớp cha/lớp cơ sở.

Parent > Trait > Child 

http://php.net/manual/en/language.oop5.traits.php

11

Bạn có thể mở rộng đặc điểm hơi. Mở rộng câu trả lời của mrlee, khi bạn use một đặc điểm, bạn có thể đổi tên phương thức của nó.

Nói ví dụ bạn có một "cha mẹ" đặc điểm đã được xác định bởi khuôn khổ của bạn:

trait FrameworkTrait { 
    public function keepMe() { 
     // Framework's logic that you want to keep 
    } 

    public function replaceMe() { 
     // Framework's logic that you need to overwrite 
    } 
} 

Đơn giản chỉ cần kéo trong đặc điểm phụ huynh, đổi tên phương pháp replaceMe của mình cho cái gì khác, và xác định phương pháp replaceMe của riêng bạn.

trait MyTrait { 
    use FrameworkTrait { 
     FrameworkTrait::replaceMe as frameworkReplaceMe; 
    } 

    public function replaceMe() { 
     // You can even call the "parent" method if you'd like: 
     $this->frameworkReplaceMe(); 

     // Your logic here 
    } 
} 

Và sau đó trong lớp học của bạn:

class MyClass { 
    use MyTrait; 
} 

Bây giờ các đối tượng của lớp này có thể làm điều này:

$obj = new MyClass(); 

$obj->keepMe();    // calls "parent" trait 
$obj->replaceMe();   // calls "child" trait 
$obj->frameworkReplaceMe(); // calls "parent" trait 
Các vấn đề liên quan