1. 程式人生 > >虛方法(virtual)\抽象方法(abstract)\介面(interface)的區別

虛方法(virtual)\抽象方法(abstract)\介面(interface)的區別

轉自:https://www.cnblogs.com/fantaohaoyou/p/9402657.html

虛方法和抽象方法都可以供派生類重寫,它們之間有什麼區別呢?

1. 虛方法必須有實現部分,抽象方法沒有提供實現部分,抽象方法是一種強制派生類覆蓋的方法,否則派生類將不能被例項化。如:

//抽象方法
public abstract class Animal
{
    public abstract void Sleep();
    public abstract void Eat();
}

//虛方法
public class Animal
{
    public virtual void Sleep(){}
    public virtual void Eat(){}
}


2. 抽象方法只能在抽象類中宣告,虛方法不是。其實如果類包含抽象方法,那麼該類也是抽象的,也必須宣告為抽象的。如:

public class Animal
{
    public abstract void Sleep();
    public abstract void Eat();
}

 

編譯器會報錯:
Main.cs(10): 'VSTest.Animal.Sleep()' is abstract but it is contained in nonabstract class 'VSTest.Animal'
Main.cs(11): 'VSTest.Animal.Eat()' is abstract but it is contained in nonabstract class 'VSTest.Animal'

3. 抽象方法必須在派生類中重寫,這一點跟介面類似,虛方法不必。如:

public abstract class Animal
{
    public abstract void Sleep();
    public abstract void Eat();
}

public class Cat : Animal
{
    public override void Sleep()
    {
        Console.WriteLine( "Cat is sleeping
" );
    }
    // we need implement Animal.Eat() here

}

 


編譯器會報錯:Main.cs(14): 'VSTest.Cat' does not implement inherited abstract member 'VSTest.Animal.Eat()',因為我們沒有實現抽象類中所有抽象方法。

 

C#中抽象類和介面的區別

大家在程式設計時都容易把抽象類和介面搞混,下面為大家從概念上講解抽象類和介面的區別:

     一、抽象類:

     含有abstract修飾符的class即為抽象類,抽象類是特殊的類,只是不能被例項化,可以建立一個變數,其型別是一個抽象類,並讓它指向具體子類的一個例項;除此以外,具有類的其他特性;重要的是抽象類可以包括抽象方法,這是普通類所不能的。抽象方法只能聲明於抽象類中,且不包含任何實現,派生類必須覆蓋它們。另外,抽象類可以派生自一個抽象類,可以覆蓋基類的抽象方法也可以不覆蓋。

    二、介面:

    介面是引用型別的,類似於類,和抽象類的相似之處有三點:     1、不能例項化;     2、包含未實現的方法宣告;     3、派生類必須實現未實現的方法,抽象類是抽象方法,介面則是所有成員(不僅是方法包括其他成員);

    介面有如下特性:

    介面除了可以包含方法之外,還可以包含屬性、索引器、事件,而且這些成員都被定義為公有的。除此之外,不能包含任何其他的成員,例如:常量、域、建構函式、解構函式、靜態成員。一個類可以直接繼承多個介面,但只能直接繼承一個類(包括抽象類)。  

   兩者的語法區別:

    1.抽象類可以有構造方法,介面中不能有構造方法。

    2.抽象類中可以有普通成員變數,介面中沒有普通成員變數

    3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。

    4. 抽象類中的抽象方法的訪問型別可以是public,protected,但介面中的抽象方法只能是public型別的,並且預設即為public abstract型別。

    5. 抽象類中可以包含靜態方法,介面中不能包含靜態方法

    6. 抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的訪問型別可以任意,但介面中定義的變數只能是public static final型別,並且預設即為public static final型別。

    7. 一個類可以實現多個介面,但只能繼承一個抽象類。

   8.介面可以用於支援回撥,而繼承並不具備這個特點.    9.抽象類實現的具體方法預設為虛的,但實現介面的類中的介面方法卻預設為非虛的,當然您也可以宣告為虛的.  

   抽象類和介面的使用:

  1.如果預計要建立元件的多個版本,則建立抽象類。抽象類提供簡單的方法來控制組件版本。

  2.如果建立的功能將在大範圍的全異物件間使用,則使用介面。如果要設計小而簡練的功能塊,則使用介面。   

 3.如果要設計大的功能單元,則使用抽象類.如果要在元件的所有實現間提供通用的已實現功能,則使用抽象類。

  4.抽象類主要用於關係密切的物件;而介面適合為不相關的類提供通用功能。

  5.好的介面定義應該是具有專一功能性的,而不是多功能的,否則造成介面汙染。如果一個類只是實現了這個介面的中一個功能,而不得不去實現介面中的其他方法,就叫介面汙染。

大家在程式設計時都容易把抽象類和介面搞混,下面為大家從概念上講解抽象類和介面的區別:

     一、抽象類:

     含有abstract修飾符的class即為抽象類,抽象類是特殊的類,只是不能被例項化,可以建立一個變數,其型別是一個抽象類,並讓它指向具體子類的一個例項;除此以外,具有類的其他特性;重要的是抽象類可以包括抽象方法,這是普通類所不能的。抽象方法只能聲明於抽象類中,且不包含任何實現,派生類必須覆蓋它們。另外,抽象類可以派生自一個抽象類,可以覆蓋基類的抽象方法也可以不覆蓋。

    二、介面:

    介面是引用型別的,類似於類,和抽象類的相似之處有三點:     1、不能例項化;     2、包含未實現的方法宣告;     3、派生類必須實現未實現的方法,抽象類是抽象方法,介面則是所有成員(不僅是方法包括其他成員);

    介面有如下特性:

    介面除了可以包含方法之外,還可以包含屬性、索引器、事件,而且這些成員都被定義為公有的。除此之外,不能包含任何其他的成員,例如:常量、域、建構函式、解構函式、靜態成員。一個類可以直接繼承多個介面,但只能直接繼承一個類(包括抽象類)。  

   兩者的語法區別:

    1.抽象類可以有構造方法,介面中不能有構造方法。

    2.抽象類中可以有普通成員變數,介面中沒有普通成員變數

    3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。

    4. 抽象類中的抽象方法的訪問型別可以是public,protected,但介面中的抽象方法只能是public型別的,並且預設即為public abstract型別。

    5. 抽象類中可以包含靜態方法,介面中不能包含靜態方法

    6. 抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的訪問型別可以任意,但介面中定義的變數只能是public static final型別,並且預設即為public static final型別。

    7. 一個類可以實現多個介面,但只能繼承一個抽象類。

   8.介面可以用於支援回撥,而繼承並不具備這個特點.    9.抽象類實現的具體方法預設為虛的,但實現介面的類中的介面方法卻預設為非虛的,當然您也可以宣告為虛的.  

   抽象類和介面的使用:

  1.如果預計要建立元件的多個版本,則建立抽象類。抽象類提供簡單的方法來控制組件版本。

  2.如果建立的功能將在大範圍的全異物件間使用,則使用介面。如果要設計小而簡練的功能塊,則使用介面。   

 3.如果要設計大的功能單元,則使用抽象類.如果要在元件的所有實現間提供通用的已實現功能,則使用抽象類。

  4.抽象類主要用於關係密切的物件;而介面適合為不相關的類提供通用功能。

  5.好的介面定義應該是具有專一功能性的,而不是多功能的,否則造成介面汙染。如果一個類只是實現了這個介面的中一個功能,而不得不去實現介面中的其他方法,就叫介面汙染。