2010-03-03 30 views
5

Her sınıfın bir dizi ortak özelliğe ve yalnızca bu sınıfa özgü bir dizi özelliğe sahip olmasını istediğim bir dizi sınıf ve karşılık gelen arabirimleri uygulıyorum. Yani, çizgisinde arayüzleri tanımlayan düşünüyorum:Çoklu Arayüz Kalıtım

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

Ben arayüzlerinde devralma sahip arasında seçim vermeye çalışan veya sınıfta duyuyorum. Yani, özellikle, bunu böyle yapın ya edebilirsiniz:

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

... ya böyle ...

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

Öyle ya da böyle gitmek için herhangi bir zorlayıcı sebep var mı

?

Güncelleme: Eğer sınıfların COM-görünür olması gerekiyorsa cevabı etkiler mi?

cevap

6

Yalnızca ve eğer IWidget1 'u uygulayan bir türün'u zorunlu kılması gerekiyorsa ve ayrıca ICommon uygularsa, arayüz kalıtımını seçmelisiniz. Her iki durumda da, sınıf hem IWidget1 hem de ICommon'u ayrı ayrı uygulayacak. Tek fark, eğer IWidget1'i ICommon'dan "türet" yaparsanız, IWidget1'in de bir ICommon olması gerektiği gerçeğini uygularsınız.

İyi bir örnek IEnumerable ve ICollection'dır. Her bir ICollection IEnumerable olarak garanti edilir, bu yüzden ICollection IEnumerable'dan gelir. Bir koleksiyon olmak ama sayılmayacak kadar yasal ya da mantıklı ise, o zaman ICollection uygulayıcıları da IEnumerable'ı uygulamak zorunda kalmayacaktı.

Seçtiğiniz hangisi COM görünürlüğünü etkilemez. .NET doğru şekilde çağırırsam, arabirimleri ayrı ayrı dışa aktarır.

+0

Doğru, evet türetmemelisiniz. Tüm Widget türleri ICommon uygulamanız GEREKİR. Bunun nedeni, her widget'daki uygulamalarını uygulamaktır. –

+1

O zaman kesinlikle IWidget1'in ICommon'dan türetilmiş olması gerekir. – Josh

3

Bir cevaba kendiniz yardım etmek için Liskov İkame Prensibi'ni kullanın.

IWidget1, ICommon1 açısından çalışan tüm istemciler için ikame edilebilirse, IWidget1'i ICommon1'den devralabilirsiniz. Çok sayıda arabirimi uygulayan sınıfla birlikte gitmiyorsanız.

+0

Bu, aynı sonucu vermiyor mu? –

+0

@Tim - detaylandırır mısınız? Demek istediğim, bir ICommon1 bekleyen tüm kodlar için bir IWidget1 nesnesinin yerini alabilir ve etki alanınızda bir IWidget1 varlığına sahip olmak mantıklıysa, arabirim miras yaklaşımıyla devam edebilirsiniz. Değilse, aynı sınıfa çoklu arayüzleri uygulayın. – Gishu

+0

Tamam Ne demek istediğini görüyorum. Teşekkürler. Yararlı yeni bir bakış açısı için –

0

Miras, sınıfın veya arabirimin niteliğine/davranışına bağlıdır. IWidget1 ve IWidget2'daki davranışlar ICommon'daki tüm davranışları içeriyorsa, IWidget1 : ICommon ve IWidget2 : ICommon gibi miras bırakabilirsiniz ve ComVisible ile ilgili bir sorun yoktur. Bu sadece OOPS konseptidir.

1

Diğer cevaplarda dikkate alınmadığımı düşündüğüm başka bir nokta daha var. Eğer ICommon dan IWidgetX türetmek ve sonra birden arayüz uygulamasını yapabilir IWidget1 ve IWidget2 hem davranışa sahip bir widget ile gelip Eğer

: her ikisi de arabirim ICommon türetilmiş olsaydı

class Widget3 : IWidget1, IWidget2 

, Daha sonra sınıfınızda iki ICommon uygulaması olacak. Bu büyük bir sorun değil ve multiple interface implementation tarafından ele alınabilir, ancak mantığı değiştirir.Eğer ICommon dan IWidgetX türetmek yoksa

Öte yandan

, sadece açık uygulanmasına uğraşmak zorunda her üç uygulama ve olamaz:

class Widget3 : IWidget1, IWidget2, ICommon 

Yani, akla eğer ihtiyacınız olabileceğini Bu Widget3 sınıfı - IwidgetX arayüzlerini ICommon

+0

+1 teşekkürler. –

+0

Teşekkürler Tim - tam olarak doğru olmadığımı ortaya çıkarsa da! Bu çoklu arabirim uygulamasına biraz daha derinden kazdım ve aslında iki ICommon uygulaması yok - eğer sahipseniz, o zaman cast (ICommon) (yeni Widget3()) çözümlenemez olacaktır. Bu durumu daha ayrıntılı olarak açıkladım [bu blog gönderisinde] (http://stefankiryazov.blogspot.com/2011/09/luke-whos-your-father-multiple.html) ICommon'dan IWidgetX türetilmesine karşı argüman yine de kısmen geçerli – Vroomfundel