2009-07-09 47 views
3

請考慮以下示例。我有一個MyInterface接口,然後是兩個抽象類MyAbstractClass1和MyAbstractClass2。 MyAbstractClass1實現MyInterface,但MyAbstractClass2不。需要幫助瞭解實現接口的抽象類

現在我有三個具體的類。

  1. MyConcreteClass1派生自MyAbstractClass1但未實現MyInterface。
  2. MyConcreteClass2派生自MyAbstractClass2,但實現了MyInterface。
  3. MyConcreteClass3從MyAbstractClass1派生,並實現MyInterface。

ConcreteClass1是否也隱含地實現MyInterface,因爲它來自MyAbstractClass1?假設MyAbstractClass1隱式地實現了MyInteface的方法,那麼ConcreteClass1不應該被轉換爲MyInterface來訪問MyInteface方法嗎?

MyAbstractClass1可以隱式實現一個MyInterface方法作爲抽象方法,但不能顯式實現一個MyInterface方法作爲抽象方法。爲什麼是這樣?

MyConcreteClass3過度是因爲它實現了一個已經由其基類實現的接口嗎?即使知道從MyAbstractClass1派生的所有類也應該實現MyInterface,是否還有一個原因會導致這樣做?

這裏的一個類圖

alt text http://files.getdropbox.com/u/113068/abstractclassesandinterfaces.png

下面的代碼:

//interface 
public interface MyInterface 
{ 
    void MyMethodA(); 
    void MyMethodB(); 
    void MyMethodC(); 

} 

//abstract classes 
public abstract class MyAbstractClass1 : MyInterface 
{ 
    public void MyMethodA() 
    { 
    } 


    void MyInterface.MyMethodB() 
    { 

    } 

    //Error: "the modifier abstract is not valid for this item" 
    //abstract void MyInterface.MyMethodC(); 

    //This works 
    public abstract void MyMethodC(); 

    public abstract void MyMethodZ(); 

} 


public abstract class MyAbstractClass2 
{ 
    public void MyMethodX() 
    { 
    } 

    public abstract void MyMethodY(); 

} 

//Concrete classes 
//ConcreteClass 1: Only Abstract class implements the interface 
public class ConcreteClass1 : MyAbstractClass1 
{ 
    public override void MyMethodC() 
    { 
    } 

    public override void MyMethodZ() 
    { 

    } 
} 

//ConcreteClass 1: Only Concrete class implements the interface 
public class ConcreteClass2 : MyAbstractClass2, MyInterface 
{ 
    public override void MyMethodY() 
    { 
    } 

    public void MyMethodA() 
    { 

    } 

    public void MyMethodB() 
    { 

    } 

    public void MyMethodC() 
    { 

    } 

} 
//ConcreteClass 1: Both concrete and abstract class implement the interface 
public class ConcreteClass3 : MyAbstractClass1, MyInterface 
{ 
    public override void MyMethodC() 
    { 

    } 

    public override void MyMethodZ() 
    { 

    } 
} 

回答

3

ConcreteClass1是否也隱式實現MyInterface,因爲它是從MyAbstractClass1派生的?

是的。

ConcreteClass1不應該被轉換爲MyInterface才能訪問MyInteface方法嗎?

正確。 (myConcreteClass1 is MyInterface)將評估true

MyAbstractClass1可以隱式實現MyInterface的方法作爲抽象方法,但不能明確實現MyInterface方法作爲抽象方法。

明確的實現是區分重疊的成員簽名。顯式實現對於您正在實現它的類是私有的,所以它不能被派生類訪問(因此不能被抽象)。您也不能強制派生自MyAbstractClass1的類明確實現MyInterface,因此無法確保抽象成員將被實現。

MyConcreteClass3過度是因爲它實現了一個已經由其基類實現的接口嗎?即使知道從MyAbstractClass1派生的所有類也應該實現MyInterface,是否還有一個原因會導致這樣做?

不一定,如果您需要顯式實現接口的成員以將其與MyConcreteClass3上的重疊成員區分開來。否則就沒有必要了。

1

在這種情況下,所有三個類實現的接口(直接或間接)。這是因爲MyAbstractClass1實現了MyInterface,並且由於MyConcreteClass1從MyAbstractClass1派生,所以也可以將MyConcreteClass1作爲MyInterface處理。只要將MyConcreteClass2視爲MyInterface,MyConcreteClass2就可以用來自MyAbstractClass1的東西處理。由於MyAbstractClass1已經實現了MyInterface,所以從ConcreteClass3中的MyInterface派生出來有點多餘。

有了所有這些信息,我想說的是,在MyConcreteClass3上實現MyInterface是多餘的,因爲它來自已經實現了MyInterface的MyAbstractClass1。 我認爲你不能有一個接口方法的抽象實現的原因是,它本身不提供代碼,你不能保證它會在子類中被覆蓋。改爲使用虛擬。

+0

爲什麼我得到一個downvote? – RCIX 2009-07-10 00:13:49

+0

「堅持」是一個不好的答案... – 2009-07-10 00:14:35

1

這不是多餘的。考慮這個班級設置,簡化...

public interface I 
{ 
    void A(); 
} 

public abstract class B : I 
{ 
    public void A() 
    { 
     Console.WriteLine("Base"); 
    } 
} 

public class D : B 
{ 
    public void A() 
    { 
     Console.WriteLine("Hide"); 
    } 
} 

public class U 
{ 
    public void M(I i) 
    { 
     Console.WriteLine("M!"); 
    } 
} 

執行此...

var d = new D(); 
var i = (I)d; 
var u = new U(); 

i.A(); 
d.A(); 
u.M(d); 
u.M(i); 

你會得到...

Base 
Hide 
M! 
M! 

如果從派生類中添加接口...

public class D : B, I 
{ 
    public void A() 
    { 
    Console.WriteLine("Hide"); 
    } 
} 

You will我得到...

Hide 
Hide 
M! 
M! 

因此,它會影響當您獲得派生類的Iness時獲得的接口方法的實現。