C#編程語言與面向對象——抽象基類與接口


在一個類前加“abstract”關鍵字,此類就成為抽象類。

對應的,在一個方法前加“abstract”關鍵字,此方法就成為抽象方法。

abstract class Fruit    //抽象類
{
        public abstract void GrowInArea();//抽象方法
}

  注意抽象方法不能又實現代碼,在方法名后直接跟一個分號。

  抽象類專用於派生出子類,子類必須實現抽象類中所生命的方法。否子子類仍是抽象類。

  抽象類一般用於表達一種比較抽象的事物,比如說“水果”,而抽象方法則說明此抽象類應該具有的某種特性。比如Fruit類中有一個抽象方法GrowInArea(),說明水果一定有一個最適合其生長的地區,但不同的水果生長是不同的。

  從統一抽象類中繼承的子類擁有相同的方法(及抽象類所定義的抽象方法),但這種方法的具體代碼每個類都可以不一樣。

  如:

  

class Apple:Fruit    //蘋果類
{
        public override void GrowInArea()
        {
            Console.WriteLine("南北方都可以種植。");
        }
}    
class Pineapple:Fruit    //菠蘿
{
        public override void GrowInArea()
        {
            Console.WriteLine("只在南方種植。");
        }
}    

上述代碼中的override關鍵字,說明子類重寫了基類的抽象方法,抽象類不能創建對象,一般用它來引用子類對象。

Fruit f;
f=new Apple();
f.GrowInArea();
f=new Pineapple();
f.GrowInArea();

結果:

南北方都可以種植。
只在南方種植。

上述幾段代碼所說,f 所引用的對象不同而輸出不同的結果。

可以按照以下公式編寫代碼:

抽象類 抽象類變量名=new 繼承自此抽象類的具體子類名();

一個抽象類中可以包含非抽象的方法和字段。因此:

包含抽象方法的類一定是抽象類,但抽象類中的方法不一定是抽象方法。

抽象屬性

abstract class Parent
{
    public abstract String Message    //抽象屬性
    {
        get;set;
    }
}    

class Child:Parent
{
    private String _msg;
    public override String Message
    {
        get
        {
            return _msg;
        }
        set
        {
            _msg=value;
        }
    }
}    

 

代碼使用:

Parent p =new Child();
p.Message="Hello";

接口

舉個例子

 

鴨子是一種鳥,會游泳,同時又是一種食物。

 

如何在面向對象的程序中表達這種關系?

因為在C#中無法繼承兩個類,所以為了解決這一問題,C#引入了接口(interface),並規定”一個類可以實現多個接口“。

關鍵在interface用於定義接口

 

//定義兩個接口
public interface ISwim
{
    void Swim();
}

public interface IFood
{
    void Cook;
}

 

接口可以看成一種”純“的抽象類,接口的所有方法都是抽象方法。

//定義一個抽象類
public abstract class Bird
{
    public abstract void Fly();
}

//繼承自一個抽象類,實現兩個接口
public class Duck:Bird,IFood,ISwim
{
    //實現ISwim接口
    public void Swim()
    {
        Console.WriteLine("是鴨子就會游泳。");
    }

    //實現IFood接口
    public void Cook()
    {
        Console.WriteLine("鴨子經常被燒烤。");
    }

    //實現抽象類Brid中的抽象方法
    public override void Fly()
    {
       Console.WriteLine("只有野鴨才會飛");
    }
}    

使用:

接口類型名 變量名=new 實現了接口的類型名();

 

代碼:

 

static void Main(string[] args)
{
    Duck d =new Duck();
    //Duck對象d可以使用3中方法:

    //1.自行定義的;

    //2.父類定義的

    //3.接口定義的

    d.Fly();

    d.Cook();

    d.Swim();

    //將子類(Duck)對象賦給基類變量

    Bird b=d;

    //現在只能使用基類定義的Fly()方法

    b.Fly();

    //將Duck對象賦給ISwim接口變量

    ISwim s=d;

    //現在只能使用接口定義的Swim()方法

    s.Swim();

    //將Duck對象賦給另一個實現的接口IFood接口變量

    IFood f=d;

    //現在只能使用接口定義的Cook()方法

    f.Cook();

}    

 

雖然程序中使用都只有一個Duck對象,但將其賦值給不同類型的變量后,其可以使用的方法是不一樣的。

 

顯示實現接口

當某個類實現多個接口,創建一個此類的對象之后,通過引用這個對象的對象變量可以訪問其所有的公有方法(包括自身的公有方法以及有接口定義的公有方法)。這種情況下,就分不清哪些方法是由接口提供,那些是有自己定義的。而C#提供餓了一種”顯示接口“實現機制,區分這兩種情況。

interface IMyInterface
{
    void func();
}

public class A:IMyInterface
{
    void IMyInterface.func()
    {
        //...
    }

    public void func2()
    {
        //...
     }
}

用粗體表示的就是C#對接口IMyInterface的顯示實現方式。

當類A顯示實現接口IMyInterface后,只能以下面方式訪問接口定義的方法:

IMyInterface a=new A();
a.func();

所以說:被顯示實現的接口方法只能通過接口實例訪問,而不能通過類實例直接訪問。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM