Trong khi một số nguyên tắc nhất định bạn nên sử dụng giao diện khi bạn muốn xác định hợp đồng cho lớp không thừa kế (IDomesticated
) và thừa kế khi lớp là phần mở rộng của lớp khác (Cat : Mammal
, Snake : Reptile
), có trường hợp (theo ý kiến của tôi) những hướng dẫn này đi vào một khu vực màu xám.Khi nào sử dụng giao diện hoặc lớp trừu tượng? Khi nào sử dụng cả hai?
Ví dụ: giả sử triển khai của tôi là Cat : Pet
. Pet
là một lớp trừu tượng. Nếu được mở rộng thành Cat : Mammal, IDomesticated
trong đó Mammal
là lớp trừu tượng và IDomesticated
là giao diện? Hoặc tôi có xung đột với nguyên tắc KISS/YAGNI (mặc dù tôi không chắc chắn liệu sẽ có một lớp học Wolf
trong tương lai không thể kế thừa từ Pet
)?
Di chuyển khỏi ẩn dụ Cat
s và Pet
s, giả sử tôi có một số lớp đại diện cho nguồn cho dữ liệu đến. Tất cả họ đều cần phải thực hiện cùng một cơ sở bằng cách nào đó. Tôi có thể thực hiện một số mã chung trong một lớp trừu tượng Source
và kế thừa từ nó. Tôi cũng có thể chỉ cần thực hiện một giao diện ISource
(mà cảm thấy nhiều hơn "đúng" với tôi) và tái triển khai mã chung trong mỗi lớp (ít trực quan hơn). Cuối cùng, tôi có thể "ăn bánh và ăn nó" bằng cách tạo cả lớp trừu tượng và giao diện. Điều gì là tốt nhất?
Hai trường hợp này mang lại điểm để chỉ sử dụng lớp trừu tượng, chỉ có giao diện và sử dụng cả lớp trừu tượng và giao diện. Có phải tất cả các lựa chọn hợp lệ này hay có "quy tắc" cho thời điểm nào nên được sử dụng trên một quy tắc khác không?
Tôi muốn làm rõ rằng bằng cách "sử dụng cả một lớp trừu tượng và một giao diện" bao gồm các trường hợp khi họ về cơ bản đại diện cho điều tương tự (Source
và ISource
cả hai đều có cùng các thành viên), nhưng lớp thêm chức năng chung trong khi giao diện chỉ định hợp đồng.
Cũng đáng lưu ý là câu hỏi này chủ yếu là cho các ngôn ngữ không hỗ trợ đa kế thừa (chẳng hạn như .NET và Java).
Tôi muốn lưu ý rằng tôi đã thấy một số câu hỏi "Giao diện so với lớp trừu tượng", nhưng trong câu hỏi này, tôi quan tâm nhất khi sử dụng * cả giao diện * và lớp trừu tượng (nếu đây là một điều hợp lệ để làm.) – Blixt
bản sao có thể có của [Giao diện vs Lớp trừu tượng (chung OO)] (http://stackoverflow.com/questions/761194/interface-vs-abstract-class-general-oo) –
bản sao có thể có của [Khi sử dụng giao diện thay vì một lớp trừu tượng và ngược lại?] (Http://stackoverflow.com/questions/479142/when-to-use-an-interface-instead-of-an-abstract-class-and -vice-versa) – nawfal