Tại sao bạn cần một giao diện, nếu đã có các lớp trừu tượng?
Để ngăn chặn nhiều kế thừa (có thể gây ra nhiều vấn đề được biết đến).
Một trong những vấn đề như vậy:
"Vấn đề kim cương" (đôi khi được gọi là "kim cương chết chóc") là một sự mơ hồ phát sinh khi hai lớp B và C thừa hưởng từ A và lớp D thừa hưởng từ cả B và C. Nếu có một phương pháp trong A mà B và C đã ghi đè và D không ghi đè lên nó, thì phiên bản nào của phương thức mà D kế thừa: phiên bản của B hoặc của C?
Nguồn: https://en.wikipedia.org/wiki/Mult Môn_inherribution#The_diamond_propet
Tại sao / Khi nào nên sử dụng giao diện?
Một ví dụ ... Tất cả các xe trên thế giới đều có cùng giao diện (phương thức) ... AccelerationPedalIsOnTheRight()
, BrakePedalISOnTheLeft()
. Hãy tưởng tượng rằng mỗi thương hiệu xe hơi sẽ có những "phương pháp" khác với một thương hiệu khác. BMW sẽ có Phanh ở bên phải và Honda sẽ có phanh ở bên trái bánh xe. Mọi người sẽ phải học cách những "phương pháp" này hoạt động mỗi khi họ mua một thương hiệu xe hơi khác. Đó là lý do tại sao nên có cùng một giao diện ở nhiều "địa điểm".
Giao diện làm gì cho bạn (tại sao ai đó thậm chí sẽ sử dụng một giao diện)? Một giao diện ngăn bạn khỏi "lỗi" (nó đảm bảo với bạn rằng tất cả các lớp thực hiện một giao diện cụ thể, tất cả sẽ có các phương thức trong giao diện).
// Methods inside this interface must be implemented in all classes which implement this interface.
interface IPersonService
{
public function Create($personObject);
}
class MySqlPerson implements IPersonService
{
public function Create($personObject)
{
// Create a new person in MySql database.
}
}
class MongoPerson implements IPersonService
{
public function Create($personObject)
{
// Mongo database creates a new person differently then MySQL does. But the code outside of this method doesn't care how a person will be added to the database, all it has to know is that the method Create() has 1 parameter (the person object).
}
}
Bằng cách này, Create()
phương thức sẽ luôn được sử dụng theo cùng một cách. Không có vấn đề gì nếu chúng ta đang sử dụng MySqlPerson
lớp học hoặc MongoPerson
lớp học. Cách chúng ta đang sử dụng một phương thức giữ nguyên (giao diện giữ nguyên).
Ví dụ: nó sẽ được sử dụng như thế này (ở mọi nơi trong mã của chúng tôi):
new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);
Bằng cách này, một cái gì đó như thế này không thể xảy ra:
new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);
Việc nhớ một giao diện dễ dàng hơn nhiều và sử dụng cùng một giao diện ở mọi nơi, hơn nhiều giao diện khác nhau.
Theo cách này, bên trong Create()
phương thức có thể khác nhau đối với các lớp khác nhau, mà không ảnh hưởng đến mã "bên ngoài", gọi phương thức này. Tất cả các mã bên ngoài phải biết là phương thức Create()
có 1 tham số ( $personObject
), vì đó là cách mã bên ngoài sẽ sử dụng / gọi phương thức. Mã bên ngoài không quan tâm những gì xảy ra bên trong phương thức; nó chỉ phải biết cách sử dụng / gọi nó.
Bạn cũng có thể làm điều này mà không cần giao diện, nhưng nếu bạn sử dụng giao diện thì sẽ "an toàn" hơn (vì nó ngăn bạn mắc lỗi). Giao diện đảm bảo với bạn rằng phương thức Create()
sẽ có cùng chữ ký (cùng loại và cùng số tham số) trong tất cả các lớp thực hiện giao diện. Bằng cách này, bạn có thể chắc chắn rằng BẤT K class lớp nào thực hiện IPersonService
giao diện, sẽ có phương thức Create()
(trong ví dụ này) và sẽ chỉ cần 1 tham số ( $personObject
) để được gọi / sử dụng.
Một lớp thực hiện một giao diện phải thực hiện tất cả các phương thức mà giao diện đó có / có.
Tôi hy vọng rằng tôi đã không lặp lại quá nhiều.