2009-06-07 220 views
3

給出如下:我可以在C#中使用子類實現接口嗎?

class A : B {} 

interface I 
{ 
B TheObject {get;set;} 
} 

我能做到這一點不知?

class C : I 
{ 
public A TheObject {get;set;} 
} 

注意接口有基類,實現有子類。

+0

如果這是可能的話,它肯定會混淆未來的代碼維護者。你的意圖是什麼?如果你遇到這個問題,你應該重構。 – 2009-06-07 03:48:46

回答

11

試試這個

class C : I 
{ 
public A TheObject {get;set;} 
B I.TheObject 
{ 
    get { return A; } 
    set { A = value as A; } 
} 
} 

您可能需要修改的B二傳手,根據您的需要。以這種方式實現接口具有以下結果。在處理類型爲C的變量時,您將無法訪問B TheObject。如果你需要,你將需要聲明一個I變量並將其分配給你的C變量。以這種方式實現我被稱爲顯式實現。

C c = new C(); 
A a = c.TheObject; // TheObject is an A 
I i = c; 
B b = i.TheObject; 
1

不,你不能。至少不是沒有C#4.0的協方差/反變量功能。

1

沒有。編譯器會抱怨類型不匹配。

另外,我不同意Paul的看法:我認爲差異對你的情況沒有幫助。 看看Skeet關於差異here的說法。

2

你不能這樣做,因爲接口實現的返回類型必須匹配。但是,我爲什麼不能這樣做的理由是錯誤的(正如評論中指出的那樣)。您必須簽名匹配,但你可以在C返回一個新的A ...

public class C : I 
{ 
    public B TheObject { get { return new A(); } set {} } 
} 
+1

我不太明白你的例子。它應該不是:A是-A B,​​但B不是A?另外,B應該是Vehicle和A Boat,我會是Mobile。然後,另一個D類飛機(這將是Vehicle)不能分配給TheObject,因爲它需要一個Boat,而不是Mobile在Mobile界面中聲明的。我錯過了什麼嗎? – 2009-06-07 03:49:26

+0

@Ionut:是的,你說得對,我需要解決。 – 2009-06-07 05:09:52

1

號,以下假設:

class D : B {} 

C c = new C(); 
c.TheObject = new D(); // error. D is not A, A is not D 

有了上面的類我仍然可以使用D與實現接口I對象,但是讓我們假設我想設置的TheObject屬性D的實例的C的實例。我不能,因爲DA是兄弟姐妹。它們都是從同一個類繼承而來的,因爲它們在接口中,但是聲明你期望A困惑編譯器。 A的實例不是D的實例,但A和D的實例都是B的實例。

此規則遵循Liskov Substitution Principle

P.S.我想感謝Troels Knak-Nielsen,讓我對這個微妙的事情大開眼界。

0

你在想什麼是協變/逆變,但即使在C#4.0中也不行。如果您只有對接口的引用,它仍然需要可用。

getter會工作,因爲A也是B,但setter將不起作用,因爲實現需要一個A,而接口允許您將TheObject設置爲B. 通常,返回值可以是子類型,並且參數可以是具有協變/逆變的基本類型。但僅限於C#4.0。

0

這編譯:

class B { } 

class A : B { } 

interface I<T> where T : B 
{ 
    T TheObject { get; set; } 
} 

class C : I<A> 
{ 
    public A TheObject { get; set; } 
} 

但我想這是不是你想要的?

相關問題