C#語法學習接口(interface)

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/3
 * Time: 下午 01:40
 * 接口(interface)
 * 接口(interface)定議了一個可由類和結構實現的協定.接口可以包含方法,屬性,事件和索引器.
 * 接口不提供它所定議的成員的實現--它公指定實現該接口的類或結構必須提供的成員.
 * 接口像一是一种協議
 * 抽像是虛方法的特例,而接口則是抽像的特例.
 
*/

using System;
interface IDrivingLicence
{
    
void GetLicence();
}
//如果一個類繼承了接口,則必需實現該接口所有的方法.
class Teacher : IDrivingLicence
{
    
public void GetLicence()
    {
        Console.WriteLine(
"獲得駕駛執照");
    }
}
class Test
{
    
static void Main()
    {
        Teacher t 
=new Teacher();
        t.GetLicence();
    }
}

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/3
 * Time: 下午 01:51
 * 聲明接口要注意的幾點
 * 1,一個接口聲明可以聲明零個或多個成員.
 * 2,接口的成員必順是方法,屬性,事件或索引器.
 * 3,接口不能包含常量,字段,運算符,實例構造函數,析構函數或類型,也不能包含任何種類的靜態成員.
 * 4,所有接口成員都隱式地有public訪問屬性.
 * 5,接口成員聲明中包含任何修飾符都屬於編譯時錯誤.
 * 具體來說,不能使用修飾符abstract,public,protected,internal,private,virtual,override,static來聲明接口成員.
 * 
 * 定議接口的規範:
 * public delegate void StringListEvent(IStringList sender);
 * public interface IStringList
 * {
 *       void Add(string s);//方法
 *       int Count{get;}//屬性
 *       event StringListEvent Changed;//事件
 *       string this[int index]{get;set;}//索引器
 * }
 
*/
using System;
interface IDrivingLicence
{
    
void GetLicence();
}
//如果一個類繼承了接口,則必需實現該接口所有的方法.
class Teacher : IDrivingLicence
{
    
public void GetLicence()
    {
        Console.WriteLine(
"獲得駕駛執照");
    }
}
class Test
{
    
static void DriverCar(string name,object o)
    {
        
//這里用了強制類型轉換
        IDrivingLicence dl=as IDrivingLicence;
        
if(dl!=null)//實現了IDrivingLicence接口的情況
        {
            Console.WriteLine(name 
+ "開動了汽車");
        }
        
else//沒有實現IDrivingLicence接口的情況
        {
            Console.WriteLine(name 
+ "沒有駕駛執照,不能開車");
        }
    }
    
static void Main()
    {
        Teacher t 
=new Teacher();
        DriverCar(
"老師",t);
    }
}

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/3
 * Time: 下午 02:21
 * 
 
*/
using System;
interface IDrivingLicenceB
{
    
void GetLicence();
}
interface IDrivingLicenceA : IDrivingLicenceB
{
    
new void GetLicence();
}
//如果一個類繼承了接口,則必需實現該接口所有的方法.
class Teacher : IDrivingLicenceA
{
    
public void GetLicence()
    {
        Console.WriteLine(
"老師獲得A類駕駛執照");
    }
}
class Student : IDrivingLicenceB
{
    
public void GetLicence()
    {
        Console.WriteLine(
"學生獲得B類駕駛執照");
    }
}
class Test
{
    
static void DriveCar(string name,IDrivingLicenceB o)
    {
        
//這里用了強制類型轉換
        IDrivingLicenceB dl=as IDrivingLicenceB;
        
if(dl!=null)//實現了IDrivingLicence接口的情況
        {
            Console.WriteLine(name 
+ "開動了卡車");
        }
        
else//沒有實現IDrivingLicence接口的情況
        {
            Console.WriteLine(name 
+ "沒有駕駛執照,不能開卡車");
        }
    }
    
static void DriveBus(string name,IDrivingLicenceB o)
    {
        
//這里用了強制類型轉換
        IDrivingLicenceA dl=as IDrivingLicenceA;
        
if(dl!=null)//實現了IDrivingLicence接口的情況
        {
            Console.WriteLine(name 
+ "開動了公共汽車");
        }
        
else//沒有實現IDrivingLicence接口的情況
        {
            Console.WriteLine(name 
+ "沒有駕駛執照,不能開公共汽車");
        }
    }
    
static void Main()
    {
        Teacher t 
=new Teacher();
        DriveCar(
"老師",t);
        DriveBus(
"老師",t);
        Student s 
= new Student();
        DriveCar(
"學生",s);
        DriveBus(
"學生",s);        
    }
}


/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/3
 * Time: 下午 02:37
 * 完全限定接口成員名
 * 接口成員有時也用它的完全限定名(fully qualified name)來引用.
 * 接口成員的完全限定名是這樣組成的:
 * 聲明該成員的接口名稱,後跟一個點,再後跟該成員的名稱.
 * 成員的完全限定名將引用聲明該成員的接口.
 * 
 * 
 * 顯示接口成員實現
 * 為了實現接口,類或結構可以聲明顯式接口成員實現
 * (explicit interface member implementation).
 * 顯式接口成員實現就是一种方法,屬性,事件或索引器聲明
 * 它使用完全限定接口成員名稱作為標識符.
 * 
 * 
 * 顯式接口實現有兩個主要用途
 * 1,由於顯式接口成員實現不能通過類或結構實例來訪問
 * 因此它們就不屬於類或結構的自身的公共接口.
 * 當需要在一個公用的類或結構中實現一權供內部使用(不
 * 允許外界訪問)的接口時,這就特別有用.
 * 2,顯式接口成員實現可以消除因同時含有多個相同簽名的
 * 接口成員所引起的多義性.如果沒有顯式接口成員實現,一
 * 個類或結構就不可能為具有相同簽名和返回類型的接口成
 * 員分別提供相應該的實現,也不可能為具相同簽名和不同
 * 返回類型的所有接口成員中的任何一個提供實現.
 * 
 * 顯式接口成員實現的總結
 * 1,在方法調用,屬性訪問或索引器訪問中,不能直接訪問"顯式接口成員實現"
 * 的成員,即使用它的完全限定名也不行."顯示接口成員實現"的成員只能通過
 * 接口實例訪問,並且在通過接口實例訪問時,只能用該接口成員的簡單名稱來
 * 引用.
 * 2,顯式接口成員實現中包含訪問修飾符屬於編譯時錯誤,而且如果包含
 * abstract,virtual,override,static修飾符也屬於編譯時錯誤.
 * 3,顯式接口成員實現具有與其他成員不同的可訪問性特徵.由於顯式接口成員
 * 實現永遠不能在方法調用或屬性訪問中通過它們的完全限定名來訪問,因此,它
 * 們似乎是private(私有的).但是,因為它們可以通過接口實例來訪問,所以它們
 * 似乎又是public(公共的).
 
*/
using System;
interface IDrivingLicenceB
{
    
void GetLicence();
}
interface IDrivingLicenceA : IDrivingLicenceB
{
    
new void GetLicence();
}
//如果一個類繼承了接口,則必需實現該接口所有的方法.
class Teacher : IDrivingLicenceA
{
    
void IDrivingLicenceB.GetLicence()
    {
        Console.WriteLine(
"老師獲得B類駕駛執照");
    }
    
void IDrivingLicenceA.GetLicence()
    {
        Console.WriteLine(
"老師獲得A類駕駛執照");
    }
    
public void GetLicence()
    {
        Console.WriteLine(
"這個不是接口的方法");
    }
}
class Test
{
    
static void Main()
    {
        Teacher t 
=new Teacher();
        ((IDrivingLicenceB)t).GetLicence();
        ((IDrivingLicenceA)t).GetLicence();
        t.GetLicence();    
    }
}



/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/3
 * Time: 下午 03:12
 * 接口的多繼承
 * 
 
*/
using System;
interface IA
{
    
void F();
}
interface IB:IA
{
    
new void F();
}
interface IC:IA
{
    
void G();
}
interface IBC:IB,IC
{
    
}
class Derive:IBC
{
    
public void F()
    {
        Console.WriteLine(
"IB.F()");
    }
    
public void G()
    {
        Console.WriteLine(
"IC.G()");
    }
}
class Test
{
    
static void Main()
    {
        
//下面用了顯示成員調用的方法
        Derive d=new Derive();
        d.F();
//通過實例名來調用F方法
        ((IA)d).F();//先找到IBC,再找到IB,最後找到IA.可是因為IA的F方法被IB的F()方法所隱藏,所以這里調用的是IB的F()方法
        ((IB)d).F();//
        ((IC)d).F();//通過d實例來調用IC的F()方法,而IC的F()方法是繼承自IA的F()方法.IC沒有覆蓋IA的F()方法,按理說顯然是可以調用到的.
                    
//可實際上還是調用的IB的F()方法,這個例子說明了接口在多重繼承的一個原則:直觀隱藏規則,簡單的說如果成員在任何一個
                    
//訪問路徑中被隱藏,那麼它在所有的訪問路徑都被隱藏.
        ((IBC)d).F();//
    }
}

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/3
 * Time: 下午 03:48
 * 接口重新實現
 * 一個類若繼承了某個接口的實現,則只要將該接口列
 * 入它的基類列表中,就可以重新實現(re-implement)
 * 該接口.
 * 接口的重新實現與接口的初始實現遵循完全上機的
 * 接口映射規則.因此,繼承的接口映射不會對重新實
 * 現該接口而建立的接口映射產生任何影響.
 
*/

using System;
interface IA
{
    
void F();
}
class B:IA
{
    
void IA.F()//這里使用顯示成員實現
    {
        Console.WriteLine(
"B.F");
    }
}
class C:B,IA
{
    
public void F()
    {
        Console.WriteLine(
"C.F");
    }
}
class Test
{
    
static void Main()
    {
        C c
=new C();
        
//B c=new C();
        ((IA)c).F();//C.F        
    }
}

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/3
 * Time: 下午 04:02
 * 接口與多態
 * 這個例子不適合用接口來實現,這里主要是前兩節的虛方法以及抽像做比較
 * 這三都都可以實現多態機制
 * 
 * 接口與抽像類的區別
 * 1,類是對對像的抽像,可以把抽像類理解為把類當作對像,抽像成的類.
 * 接口只是一個行為的規範或規定.接口表述的是"我能做"(Can-do),抽
 * 像類更多的是定在一系列緊密相關的類間(Is-a),而接口大多數是關系
 * 疏鬆但都實現某一功能的類中.
 * 2,接口基本上不具備繼續的任何具體特點,它僅僅承諾了能夠調用的方法.
 * 3,一個類一次可以實現若干個接口,但是只能擴展一個父類.
 * 4,抽像類實了oop中的一個原則,把可變的與不可變的分離.抽像類和接口就是定義為
 * 不可變的,而把可變的由子類去實現.
 * 5,好的接口定議應該是具有專一功能性的,而不是多功能的,否則造成接口污染.如果
 * 一個類只是實現了這個接口中的一個功能,而不得不去實現接口中的其他方法,就叫
 * 接口污染.
 * 6,如果抽像類實現接口,則可以把接口中方法映射到抽像類中作為抽像方法而不必實
 * 現,而在抽像類的子類中實接口中方法.
 * 
 * 
 * 接口與抽像類的總結
 * 1,抽像類用於部份實現一個類,再由用戶按需求對其進行不同的擴展和完善;
 * 接口只是定議一個行為的規範或規定.
 * 2,抽像類在組件的所有實現間提供通用的已實現功能;接口創建在大範圍全
 * 異對像間使用的功能.
 * 3,抽像類主要用於關系密切的對你;而接口適合為不相關的類提供通用功能.
 * 4,抽像類主要用於設計大的功能單元;而接口用於設計小而簡煉的功能塊.
 * 
 *
 * 
 
*/

using System;
interface IEmployee
{
    
void StartWork();
}
class Manager : IEmployee
{
    
private string _name;
    
public Manager(string name)
    {
        _name
=name;
    }
    
public void StartWork()
    {
        Console.WriteLine(_name 
+ "給員工下達任務");
    }
}
class Secretary : IEmployee
{
    
private string _name;
    
public Secretary(string name)
    {
        _name
=name;
    }
    
public void StartWork()
    {
        Console.WriteLine(_name 
+ "協助經理");
    }
}

class Seller : IEmployee
{
    
private string _name;
    
public Seller(string name)
    {
        _name
=name;
    }
    
public void StartWork()
    {
        Console.WriteLine(_name 
+ "銷售產品");
    }
}
class Accountant : IEmployee
{
    
private string _name;
    
public Accountant(string name)
    {
        _name
=name;
    }
    
public void StartWork()
    {
        Console.WriteLine(_name 
+ "管理公司財政");
    }
}
class Test
{
    
static void Main()
    {
        IEmployee[] emp
=new IEmployee[5];
        emp[
0]=new Manager("經理張三");
        emp[
1]=new Secretary("助理李四");
        emp[
2]=new Seller("王五");
        emp[
3]=new Seller("馬六");
        emp[
4]=new Accountant("錢七");
        Console.WriteLine(
"早上八點,開始工作.");
        
foreach(IEmployee e in emp)
        {
            e.StartWork();
        }
    }
}
posted @ 2008-09-03 16:50  Athrun  阅读(598)  评论(0编辑  收藏  举报