2010-03-03 46 views
5

Tôi đang triển khai một tập hợp các lớp và giao diện tương ứng nơi tôi muốn mỗi lớp có một tập hợp các thuộc tính chung và một tập hợp các thuộc tính chuyên biệt chỉ dành riêng cho lớp đó. Vì vậy, tôi đang xem xét việc xác định giao diện dọc theo các dòng:Thừa kế nhiều giao diện

interface ICommon {...} // Members common to all widgets 
interface IWidget1 {...} // specialized members of widget type 1 
interface IWidget2 {...} // specialized members of widget type 2 

Tôi đang cố gắng chọn giữa việc thừa kế trong giao diện hoặc trong lớp. Vì vậy, đặc biệt, tôi có thể làm điều đó như thế này:

interface IWidget1 : ICommon {...} 
interface IWidget2 : ICommon {...} 
class Widget1 : IWidget1 {...} 
class Widget2 : IWidget2 {...} 

... hay như thế này ...

class Widget1: ICommon, IWidget1 {...} 
class Widget2: ICommon, IWidget2 {...} 

Có bất kỳ lý do thuyết phục để đi cách này hay cách khác?

Cập nhật: Điều đó có ảnh hưởng đến câu trả lời nếu các lớp phải được hiển thị COM không?

Trả lời

6

Bạn nên chọn kế thừa giao diện nếu và chỉ khi một loại triển khai IWidget1 phải cũng triển khai ICommon. Trong cả hai trường hợp, lớp sẽ triển khai cả IWidget1 và ICommon riêng biệt. Sự khác biệt duy nhất là nếu bạn làm cho IWidget1 "lấy được" từ ICommon bạn thực thi thực tế rằng một IWidget1 cũng phải là một ICommon.

Một ví dụ điển hình là IEnumerable và ICollection. Mỗi ICollection được đảm bảo là IEnumerable, do đó ICollection xuất phát từ IEnumerable. Nếu nó là hợp pháp hoặc có ý nghĩa là một bộ sưu tập nhưng không được liệt kê, thì những người thực hiện ICollection cũng sẽ không phải thực hiện IEnumerable nữa.

Cho dù bạn chọn sẽ không ảnh hưởng đến khả năng hiển thị COM. .NET sẽ vẫn xuất các giao diện riêng nếu tôi nhớ chính xác.

+0

Đúng vậy. Tất cả các loại Widget phải thực hiện ICommon. Đó là lý do cho nó, để thực thi việc thực hiện nó trong mỗi và mọi widget. –

+1

Sau đó, yeah bạn chắc chắn nên có IWidget1 lấy được từ ICommon. – Josh

3

Sử dụng nguyên tắc thay thế Liskov để giúp bạn trả lời.

Nếu IWidget1 có thể được thay thế cho tất cả các máy khách đang làm việc theo điều khoản của ICommon1, thì bạn có thể kế thừa IWidget1 từ ICommon1. Nếu không đi với lớp thực hiện nhiều giao diện.

+0

Điều đó không tạo ra kết quả tương tự? –

+0

@Tim - bạn có thể xây dựng không? Ý tôi là nếu bạn có thể thay thế một đối tượng IWidget1 cho tất cả các mã mong đợi một ICommon1 và nó có ý nghĩa để có một thực thể IWidget1 trong miền của bạn, thì bạn có thể đi với cách tiếp cận kế thừa giao diện. Nếu không, có cùng một lớp thực hiện nhiều giao diện. – Gishu

+0

OK Tôi hiểu ý của bạn là gì. Cảm ơn. –

0

Quyền thừa kế phụ thuộc vào thuộc tính/hành vi của lớp hoặc giao diện. Nếu hành vi trong IWidget1IWidget2 bao gồm tất cả các hành vi trong ICommon, thì bạn chắc chắn có thể kế thừa như IWidget1 : ICommonIWidget2 : ICommon và không có vấn đề gì liên quan đến ComVisible. Đây chỉ đơn giản là khái niệm OOPS.

1

Có một cân nhắc khác mà tôi cho rằng đã không được tính đến trong các câu trả lời khác.

Nếu bạn lấy được IWidgetX từ ICommon, và sau đó đưa ra một widget mà có hành vi của cả hai IWidget1 và IWidget2 bạn có thể làm nhiều giao diện thực hiện:

class Widget3 : IWidget1, IWidget2 

Nếu cả hai là giao diện được lấy từ ICommon, sau đó bạn sẽ có hai triển khai ICommon trong lớp học của bạn. Đó không phải là một vấn đề lớn và có thể được xử lý bởi multiple interface implementation, nhưng nó thay đổi logic.

Mặt khác, nếu bạn không lấy được IWidgetX từ ICommon, bạn có thể chỉ cần thực hiện cả ba và không phải đối phó với thực hiện rõ ràng:

class Widget3 : IWidget1, IWidget2, ICommon 

Vì vậy, nếu nó có thể tưởng tượng rằng bạn có thể cần lớp Widget3 như vậy - bạn không nên lấy được giao diện IWidgetX từ ICommon

+0

+1 cảm ơn vì một viễn cảnh mới hữu ích. –

+0

Cảm ơn Tim - mặc dù nó chỉ ra rằng tôi không chính xác đúng! Tôi đào sâu hơn một chút vào điều này thực hiện nhiều giao diện và thực sự bạn không có hai triển khai ICommon - nếu bạn đã có, sau đó các diễn viên (ICommon) (new Widget3()) sẽ không thể giải quyết. Tôi đã mô tả tình huống chi tiết hơn [trong bài đăng trên blog này] (http://stefankiryazov.blogspot.com/2011/09/luke-whos-your-father-multiple.html) Đối số chống lại phát sinh IWidgetX từ ICommon vẫn còn một phần hợp lệ mặc dù – Vroomfundel

Các vấn đề liên quan