Một lớp có thể mở rộng cả một lớp và triển khai Giao diện không


100

Một lớp có thể mở rộng cả một giao diện và một lớp khác trong PHP không?
Về cơ bản, tôi muốn làm điều này:

interface databaseInterface{
 public function query($q);
 public function escape($s);
 //more methods
}

class database{ //extends both mysqli and implements databaseInterface
 //etc.
}

Làm thế nào để làm điều này, chỉ cần làm:

class database implements databaseInterface extends mysqli{ 

dẫn đến một lỗi nghiêm trọng:

Lỗi phân tích cú pháp: lỗi cú pháp, T_EXTENDS không mong muốn, chờ đợi '{' trong * tệp * trên dòng * dòng *

18
Làm thế nào là điều này quá bản địa hóa?! "Câu hỏi này không chắc sẽ giúp ích cho bất kỳ du khách nào trong tương lai". Tuy nhiên, câu trả lời tốt nhất có 33 lượt bình chọn và câu hỏi 4 sao!
lưỡng tính_

Câu trả lời:


177

Hãy thử theo cách khác:

class database extends mysqli implements databaseInterface { ...}

Điều này sẽ hoạt động.


Ahh, cảm ơn bạn rất nhiều. Tại sao chính xác là họ nên làm theo cách khác?
Pim Jager

14
Vì bạn chỉ có thể kế thừa một lớp và bạn có thể triển khai bất kỳ số lượng giao diện nào, nên nó có thể là một thứ đường cú pháp. Ngoài ra, hãy nhớ rằng, nếu lớp con của bạn triển khai bất kỳ giao diện nào, giao diện đó cũng sẽ hiển thị trong danh sách các phương thức được triển khai. Vì vậy, đặt chúng theo thứ tự đó có ý nghĩa nhất định.
Drew

Nó có phải là một thực hành xấu?
Mohammed Shamshid

21

Có nó có thể. Bạn chỉ cần giữ lại thứ tự chính xác.

class database extends mysqli implements databaseInterface { ... }

Hơn nữa, một lớp có thể triển khai nhiều hơn một giao diện. Chỉ cần tách chúng bằng dấu phẩy.

Tuy nhiên, tôi cảm thấy có nghĩa vụ phải cảnh báo bạn rằng việc mở rộng lớp mysqli là một ý tưởng cực kỳ tồi . Tính kế thừa có lẽ là khái niệm được đánh giá quá cao và bị lạm dụng nhiều nhất trong lập trình hướng đối tượng.

Thay vào đó, tôi khuyên bạn nên làm những thứ liên quan đến db theo cách mysqli (hoặc cách PDO).

Thêm vào đó, một điều nhỏ nhặt, nhưng quy ước đặt tên rất quan trọng. Khi đó, lớp của bạn databasecó vẻ tổng quát hơn mysqli, do đó, nó gợi ý rằng lớp sau kế thừa từ đó databasechứ không phải ngược lại.


1
Tại sao mở rộng lớp mysqli là một ý tưởng tồi?
Pim Jager

11
Thứ nhất, vì nó không phải của bạn. Khi những kẻ mysqli quyết định thay đổi thứ gì đó, hành vi của lớp con cũng sẽ thay đổi. Thứ hai, tính kế thừa được sử dụng để CHUYÊN NGÀNH, không phải TIỆN ÍCH với chức năng bổ sung. Đây là điều dễ hiểu lầm nhất trong OOP. Theo nguyên tắc chung, tôi có xu hướng chỉ mở rộng các lớp trừu tượng.
Michał Rudnicki

Michal - thay đổi đối với mysqli sẽ khác như thế nào đối với một nhà phát triển sử dụng phương pháp đa hình so với phương pháp tổng hợp / tổng hợp? Bạn vẫn phải cập nhật mã của mình để xử lý các thay đổi.
Peter Bailey

2
Tôi quen thuộc với mẫu bộ điều hợp. Tôi chỉ nói rằng nếu tên phương thức thay đổi hoặc không được dùng nữa, bạn vẫn cần phải thay đổi mã trong cả hai trường hợp. Mặc dù tôi đồng ý rằng cách tiếp cận không đa hình sẽ tốt hơn trong trường hợp này, nhưng tôi không quan niệm rằng bộ điều hợp sẽ "miễn nhiễm" với sự thay đổi.
Peter Bailey

2
Bạn sẽ chỉ phải thay đổi mã bộ điều hợp, không phải tất cả các nơi sử dụng mã đó. Với thành phần, bạn có thể cung cấp lớp tương thích bất kể thế nào, trong khi với tính kế thừa, tốt nhất bạn có thể gọi nó là hack. Và, tôi đã sửa chữa, bộ chuyển đổi sẽ cung cấp khả năng miễn nhiễm tốt hơn để thay đổi.
Michał Rudnicki

6

vâng, trên thực tế, nếu bạn muốn triển khai nhiều giao diện, bạn có thể làm như sau:

public class MyClass extends BaseClass implements myInterface1, myInterface2, myInterface3{ 

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.