2012-12-13 159 views
1

嗨,夥計們,我是新來的C#, 我找到了微軟的下面的答案,推薦使用接口和抽象。設計與接口和抽象類

如果您預計創建組件的多個版本,請創建一個抽象類。抽象類爲您的組件版本提供了一種簡單而簡單的方法。通過更新基類,所有繼承類都會隨着更改而自動更新。另一方面,接口一旦創建就無法更改。如果需要新版本的界面,則必須創建一個全新的界面。

你是什麼意思創建組件的多個版本。請你詳細說明一下。

+0

問題2應該是一個單獨的問題。這裏有一個快速鏈接來幫助你,雖然http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx –

+1

我已經刪除了問題2,因爲在堆棧溢出只有一個問題是一次問(for好理由)。請單獨提問(更好,谷歌 - 它已經被回答了!)。 – usr

+0

搜索MSDN以創建多個版本組件.net – Paparazzi

回答

4

當您使用基類時,擁有共享某種行爲和/或屬性的相似類。其中一個典型例子是形狀。你可以是這樣的:

抽象基類 - FourSidedShape

  • 有加四面一起GetPerimeter方法。
  • 擁有GETAREA方法,即抽象(必須由派生類定義)

派生類 - 矩形

  • 自動獲得免費
  • 的getPerimeter方法具有實現GETAREA方法,使用長度x寬度

派生類 - 平行四邊形

  • 自動獲得免費
  • 的getPerimeter方法來實現GETAREA方法,利用基地x高

你的派生類還可以添加任何獨特的行爲,他們想要的是不是基本的組成部分類。

注:抽象類是不能直接安裝的類。您必須使用其中一個派生類。

3

這些確實應該是兩個問題,但我會回答他們兩個。

第二個第一:可空類型的用法是:

decimal? priceFromDb = datarow.Field<decimal?>("price"); 

在這種情況下,你聲明一個類,將舉行一個十進制值,但也可能是無效的,因爲,在這種情況下,它來自數據庫,並且可能基礎字段可能爲空。聲明可空類型的正確方法是在類型名稱的末尾使用?。然後,當你想使用有問題的值,你會做這樣的事情:

if (priceFromDb.HasValue) 
{ 
    Console.WriteLine("The price is {0}.", priceFromDb.Value); 
} 

第一個問題: 接口是在C#中使用,以確保一個類或結構實現你的一些關鍵特性需要。他們通常只包含少量的方法,通常不會超過一兩個,而且這個想法是,一旦你創建了一個發佈的界面,它就不會改變。另一方面,抽象類使您能夠強制類實現您需要的方法,併爲它們提供常用功能,並且如果將來對抽象類進行了更改,例如添加更多常見功能,繼承類自動獲取功能。使用抽象類不是取消突變的許可證,它只是一種將常用功能組合成更清晰功能的類的方法。我可以描述的最好方法是使用抽象類來定義對象及其子對象的核心屬性,並使用接口來描述類的一個關鍵行爲。

如果在.Net框架看一看,你會發現最通常被用來執行對象,而不是它的整個結構上的行爲接口(IEquatableIDisposableIComparable)的。

作爲一個例子,考慮一個抽象類車輛:

abstract class Vehicle 
{ 
    public int NumWheels { get; set; } 
    public string Name { get; set; } 
    public abstract void Drive(); 
    public override string ToString() 
    { 
     return "I am a vehicle!"; 
    } 
} 

您可以創建一個從汽車繼承的車對象,並且將需要實現Drive(),但會得到兩個屬性NumWheelsName免費。你的繼承類的車也可以重載ToString()如果它想,還是保留原樣:

public class Car : Vehicle 
{ 
    public override void Drive() 
    { 
     // your implementation here 
    } 

    public override string ToString() 
    { 
     return "I am a car!"; 
    } 
} 
0

可能是「差abstract class和interface之間」是被要求在.net世界上最常見的問題。我將解釋理論上在代碼片段之後的區別。

理論上根據我,基本上有抽象類和接口5倍之間的差異被列出如下: -

  1. 一個類可以實現任何數目的接口,但一個子類可以至多隻能使用一個抽象類。

  2. 抽象類可以具有非抽象方法(具體方法),而在接口的情況下,所有方法都必須是抽象的。

  3. 抽象類可以聲明或使用任何變量,而不允許接口這樣做。 所以下面的代碼不會編譯: -

接口TestInterface

{

int x = 4; // Filed Declaration in Interface 

void getMethod(); 

string getName(); 

}

抽象類TestAbstractClass

{

int i = 4; 
int k = 3; 
public abstract void getClassName(); 

}

它會生成一個編譯時錯誤爲: -

錯誤1個接口不能包含字段。

所以我們需要省略Field Declaration以便正確編譯代碼。

接口TestInterface

{

void getMethod(); 
string getName(); 

}

抽象類TestAbstractClass

{

int i = 4; 
int k = 3; 
public abstract void getClassName(); 

}

上面的代碼編譯正確,因爲Interface中沒有字段聲明。

4.抽象類可以有構造函數聲明,而接口不能這樣做。

所以下面的代碼不會編譯: -

接口TestInterface {

// Constructor Declaration 
public TestInterface() 
{ 
void getMethod(); 
string getName(); 
} 

}

抽象類TestAbstractClass

{

public TestAbstractClass() 
{ 
int i = 4; 
int k = 3; 
public abstract void getClassName(); 
} 

}

上面的代碼會產生一個編譯時錯誤爲: -

錯誤1個接口不能包含構造

因此,我們需要從接口省略爲了編譯我們的代碼構造函數聲明。

下面的代碼編譯完美: -

接口TestInterface {

void getMethod(); 
string getName(); 

}

抽象類TestAbstractClass {

public TestAbstractClass() 
{ 
int i = 4; 
int k = 3; 
public abstract void getClassName(); 

} 

}

5.抽象類允許所有成員聲明擁有所有訪問修飾符,而在接口中,由於接口的所有成員都是隱式公共的,我們無法聲明任何訪問修飾符(包括public)。

注意:這裏我說的是接口成員的訪問說明符,而不是接口。

下面的代碼將更好地解釋它: -

這是完全合法的給予提供訪問說明符爲公共(請記住唯一公開允許)

公共接口TestInterface

{

void getMethod(); 
string getName(); 

}

以上代碼完美編譯。

不允許爲接口的成員提供任何訪問說明符。

接口TestInterface

{

public void getMethod(); 
public string getName(); 

}

上面的代碼會產生一個編譯時錯誤爲: -

錯誤1修改 '公共' 是不適用於此項目。

但是聲明接口的最好方法是避免接口中的訪問說明符以及接口成員。

接口測試

{

void getMethod(); 
string getName(); 

}