黑马程序员_接口

来源:互联网 发布:c语言怎么输出空格 编辑:程序博客网 时间:2024/04/19 12:59

------- Windows Phone 7手机开发、.Net培训、期待与您交流! ------- 

使用接口

接口(interface)定义一种协议,它本身不提供自己定义的成员的实现,仅仅指定实现该接口的类或结构必须提供的成员。类或结构可以实现接口,同时必须遵循该协议。根据需要,一个类或结构可以实现一个或多个接口。接口可以包含4种成员:方法、属性、事件和索引器。

声明接口

同类和结构一样,接口在使用之前也必须声明。声明接口需要使用interface关键字.

声明一个名称为Iinterface的接口。

public interface Iinterface        //声明一个接口Iinterface

}

设定接口的访问权限

接口也有相应的访问权限,因此使用接口修饰符来限定它。接口修饰符一般位于接口声明中的interface关键字之前,共包括5个修饰符:new、public、protected、internal和private。

public修饰符:表示该接口是公开的,访问不受限制。

protected修饰符:表示该接口只能是本身或其派生的接口访问。

internal修饰符:表示该接口只能是在当前应用程序中访问。

private修饰符:表示该接口只能是本身访问。

new修饰符仅允许在类中定义的接口中使用,它指定接口隐藏同名的继承成员。

声明两个类:Class1和Class2,且Class2类继承于Class1类。Class1和Class2类都包含一个各自声明的接口成员Iinterface。因为Class2类继承于Class1类,因此它也继承Class1类的接口成员Iinterface。此时,Class2类就包含2个名称为Iinterface的接口成员。为了不产生冲突,在Class2类中,特意使用new修饰符隐藏Class1类的接口成员Iinterface。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication
{
    public class Class1
    {
        public interface Iinterface  //定义接口
        {
            void Print();
        }
    }
    public class Class2 : Class1
    {
        new public interface Iinterface        //使用new隐藏Class1的接口
        {
            void Print();
        }
        public void Print()
        {
            Console.WriteLine("Print");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Class2 C2 = new Class2();
            C2.Print();
            Console.ReadKey();
        }
    }
}


 

Class2.Iinterface表示Class2类中声明的Iinterface接口。如果不使用new,就会生成一个警告,

警告信息为:”示例Class2.Iinterface”隐藏了继承的成Class1.Iinterface”。如果是有意隐藏,请使用关键字new。

继承接口

在程序开发中,有一些接口是通用的。通过继承可以创建通用接口,该接口定义一组共有的标准。接口可以继承于一个或多个其他接口,也可以不继承。被继承的接口称为该接口的显式基接口。当一个接口具有一个或多个显式基接口时,在声明该接口时,接口标识符后就要紧跟一个冒号和一个由逗号(,)分隔的基接口标识符列表。

声明3个接口:Iinterface1、Iinterface2和Iinterface3。其中,Iinterface3接口继承于Iinterface1和Iinterface2接口,即Iinterface1和Iinterface2接口都是Iinterface3接口的显式基接口。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication
{
    interface Iinterface1
    {
        void Print1();
    }
    interface Iinterface2
    {
        void Print2();
    }
    class Program
    {
        interface Iinterface3 : Iinterface1, Iinterface2    //接口的继承
        {
            void Print3();
        }
        void Print1()
        {
            Console.WriteLine("Iinterface1接口的方法Print1()的实现");
        }
        void Print2()
        {
            Console.WriteLine("Iinterface1接口的方法Print2()的实现");
        }
        void Print3()
        {
            Console.WriteLine("Iinterface3接口的方法Print3()的实现");
        }
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Print1();
            p.Print2();
            p.Print3();
            Console.ReadKey();
        }
    }
}

注意:接口不能从自身直接或间接继承,否则会发生编译时错误。

接口的组成

接口可以不包含任何成员,也可以包含多个成员。它包含的成员必须是方法、属性、事件或者索引器。接口的成员默认具有public访问属性,在声明它们时不能包含任何修饰符,否则会发生编译错误。

注意:一个接口的成员包括两部分:由接口本身声明的成员和其从基接口继承的成员。

属性

接口的属性和类的属性大致相同,但是在接口中声明属性时,只能声明该属性具有哪个访问器(如get或set访问器),而不能实现该访问器。接口属性的访问器只用于表明该属性是只读的、只写的或者读写的,访问体只允许为一个分号(;)。

在Iinterface接口中声明名称为Name的属性,该属性包含get访问器和set访问器,因此,该属性是可读写的。

public interface Iinterface  //定义一个接口Iinterface

{   

   string Name                 //定义Name属性   

   {       

       get;                     //get访问器       

       set;                     //set访问器   

    }

}

注意:接口属性的访问器体只能是一个分号(;),不能包括其实现代码。

索引器

在接口中声明索引器时,只声明它有哪个访问器(get或者set访问器),而不去具体实现索引器功能。接口索引器的访问器用来标明该索引器是只读的、只写的还是读写的,访问体必须是一个分号(;)。

在Iinterface接口中声明一个索引器,该索引器只包含get访问器,因此,该索引器是只读的。

public interface Iinterface   //定义接口Iin terface

{

    string this [int index]    //定义接口索引器   

    {

        get;                       //get访问器   

     }

}

注意:接口索引器的访问器体只能是一个分号(;),不能包括其实现代码。

方法

接口中声明方法和类中相似,但是在接口中声明方法时,只能声明该方法的签名,而不能包括该方法的实现代码。该方法的方法体只能为分号(;)。

在Iinterface接口中声明一个签名为void GetName(string s);的方法。该方法的方法参数只包含一个类型为string的、名称为s的参数。该方法的返回类型为空。

public interface Iinterface   //定义接口Iinterface

{

    void GetName(string s);    //定义接口方法GetName(string s)

}

注意:接口方法的方法体只能是一个分号(;),不能包括其实现代码。

事件

和接口中属性、索引器、方法的声明一样,在接口中声明事件时,只能声明该事件的签名。而且事件的名称之后必须接一个分号(;)。

在Iinterface接口中声明一个名称为Print的事件。该事件的类型为EventHandler,它是一个委托

interface Iinterface

{

    event EventHandler Print;       //在接口Iinterface中声明一个事件

}

实现接口

在接口中只定义属性、索引器、方法、事件的声明,并不具体实现。接口是在类或者结构中实现。如果某个类或结构实现了一个或多个接口,那么在声明该类或结构时,将实现的接口的标识符包含在该类或结构的基类列表中。

声明一个接口和一个类,它们的名称分别为Iinterface和Program。其中,Program类需要实现Iinterface接口。因此,在声明Program类时,需要把Iinterface接口的标识符包含在Program类的基类列表中。

interface Iinterface            //声明Iinterface接口

{

}

//声明Program类,它的基类列表包含了Iinterface接口,因此,它实现了Iinterface接口

public class Program:Iinterface

{  

}

注意:如果一个类或结构实现某接口,则它还隐式实现该接口的所有基接口,不管该类或结构的基类列表中是否显式包含了该接口的基接口。

声明一个名称为Iinterface的接口,它包含4个成员:Name属性、索引器、GetName(string s)方法和Print事件。

interface Iinterface

{

     string Name                     //Name属性

     {

         get;                    //get访问器,表示该属性是可读的

         set;                     //set访问器,表示该属性是可写的

     }

     string this [int index]      //索引器

     {

         get;                //get访问器,表示该索引器是可读的

     }

     void GetName(string s)

     {

         ;

     }

     event EventHandler Print;

}

实现属性

接口中定义好属性后,在继承该接口的类或结构中去实现它。实现接口属性即添加该接口属性的实现代码,接口属性的名称和实现该接口属性的名称相同

在Program类中实现Iinterface接口的Name属性,并为该属性添加get访问器和set访问器。

public interface Iinterface

{

   string Name         //定义属性

   {

      get;

      set; 

   }

}

class Program : Iinterface

{

   public string Name

   {

      get

      {

           return "张三";

      }

      set

      {

           Name = value;

      }

   }

   static void Main(string[] args)

   {

       Program p = new Program();

       Console.WriteLine(p.Name);

   }

}

实现索引器

接口中定义好索引器后,在继承该接口的类或结构中去实现它。实现接口索引器即添加该接口索引器的实现代码。

Program类中实现Iinterface接口的索引器,并为该索引器添加get访问器。

piblic interface Iinterface       //定义接口Iinterface

{

   string this [ int index]      //定义索引器

   {

      get;

   }

}

class Program : Iinterface

{

   public string this [int index]      //实现索引器

   {

      get

      {

         return "张三";

      }

   } 

static void Main(string[] args)

{

   Program p = new Program();

   for(int i=0;i<2;i++)                      //循环打印索引器的内容

   {

      Consloe.WriteLine(p.[i]);

   }

}

}

实现方法

接口中定义好方法后,在继承该接口的类或结构中去实现它。实现接口方法即添加该接口方法的实现代码,接口方法的名称和实现该接口方法的签名相同

在Program类中实现Iinterface接口的GetName(string s)方法。

public interface Iinterface

{

   void GetName(string s);          //定义接口方法

}

class Program : Iinterface

{

   public void GetName(string s)    //实现接口GetName(string s)方法

   {

      Console.WriteLine("实现接口GetName(string s)方法");

      Console.WriteLine("s = "+ s);

   }

   static void Main(string[] args)

   {

      Program p = new Program();

      p.GetName("Name");

      Colsole.ReadLine();

   }

}

实现事件

接口中定义好事件后,在继承该接口的类或结构中去实现它。实现接口事件即添加该接口事件的实现代码,接口事件的名称和实现该接口事件的签名相同。

在Program类中实现Iinterface接口的event EventHandler Print事件。

public interface Iinterface    //定义接口Iinterface

{

   event EventHandler Print;    //定义接口事件Print

}

public class Program : Iinterface //Program 类继承接口 Iinterface

{

   event EventHandler print;

   event EventHandler Iinterface.Print      //实现接口事件 Print

   {

      add { print += value }                // add访问器向 print 注册事件

      remove { print -= value }          // remove 移出事件

   }

   public void F()

   {

      EventHandler handler  = print;

      if ( handler != null )

      {

         handler( this , new EventHandler() );

      }

   }

}

public class A

{

   public A( Program p )     // A类的构造函数参数是一个对象p

   {

      Iinterface i = (Iinterface)p;

      i.Print += new EventHandle( i , Print );

   }

   viud i_Print ( object  sender , EventHandler  e)

   {

      Console.WriteLine("实现了接口Iinterface 的事件 Print");

   }

}

public class test

{

   static void Main(string[] args)

   {

      Console.WriteLine("接口的事件的事列:\n");

      Program p = new Program();

      A  a = new A( p );

      p.F();

      Console.ReadLine();

   }

}

注意:在实现事件时,需要add访问器remove访问器。add访问器用来注册一个事件,remove访问器用来移除一个事件。其中,被注册或移除的事件都用默认参数value表示。

抽象类-接口

在C#开发中,如果只希望描述功能而不知道具体实现,那么开发人员必须在接口和抽象类这两者之间进行取舍。

通常的规则是:

如果可以充分描述“做什么”而不涉及任何具体的“如何做”,就应使用接口。

如果需要包含一些实现细节,那么就应使用抽象类表达这些含义。

学习使用抽象类和接口的区别。抽象类使用abstract修饰符,它用于表示所修饰的类是不完整的,并且它只能用作基类。抽象类与非抽象类在以下4个方面的区别。

抽象类不能直接实例化。如果抽象类使用new运算符,则发生编译时错误。

允许(但不要求)抽象类包含抽象成员。

抽象类不能被密封。

当从抽象类派生非抽象类时,这些非抽象类必须实现所继承的所有抽象成员,即重写这些抽象成员。

声明3个类:Class1、Class2和Program。Class1和Class2类为抽象类,Class2类继承于Class1类,Program类又继承于Class2类。另外,Class1类还包含一个抽象方法F()。由于Class1类包含抽象方法F(),因此Program类必须重写Class1类的抽象方法F()。

abstract class Class1             //声明抽象类

{

   public abstract void F();          //声明抽象方法

}

abstract class Class2 : Class1

{

   public void G()

   {

       Console.WriteLine(" Class2 类的方法 G() ");

   }

}

class Program : Class2      //  Program 类继承 Class2

{

   public override void F()

   {

      Console.WriteLine("重写了基类的方法 F() ");

   }

   static void Main(string[] args)

   {

      Program p = new Program();

      p.F();

      P.G();

      Console.ReadLine();

   }

}

注意:Class2类未提供F()方法的实现,因此,它必须也声明为抽象类。Program类重写了F()方法,而且不包含抽象成员,因此,Program类可以(但非必须)声明为非抽象类。

接口使用interface修饰符,它定义一种协议,实现该接口的类或结构必须遵循该协议。它和抽象类存在以下的区别。

一个类能实现多个接口,但只能有一个父类。

接口中不能包含非抽象方法,但抽象类中可以有。

抽象类是一个不完整的类,需要进一步细化;而接口只是一个行为的规范,即一种协议。

接口并不属于继承结构,它实际与继承无关,因此无关的类也可以实现同一个接口。

接口基本不具备继承的任何基本特点,它只是承诺了能够调用的方法。

接口可以用于支持回调,用于回调的接口仅仅是提供指向方法的指针。

 

------- Windows Phone 7手机开发、.Net培训、期待与您交流! ------- 

原创粉丝点击