C#中的接口

来源:互联网 发布:mac缺少图像源地址 编辑:程序博客网 时间:2024/06/10 15:42

  • 接口
    • 如何定义接口
    • 接口的继承
    • 调用接口
  • 显式接口

之前的学习中,学习了C#中的继承,但是C#并不支持多重继承,也就是说如果一个子类想要同时继承2个及以上基类的属性、方法,C#是不允许的。为了解决这个问题,C#用接口来“代替”多重继承。

接口:

接口是对一组方法声明的统一命名,但这些方法没有提供任何实现。也就是说,在接口中声明一组方法,但不提供实现,而继承该接口的类需要实现这些方法。比如说:一个“吃”接口中声明了很多方法:细嚼慢咽、狼吞虎咽、津津有味,但不能具体说明每种吃的方法是如何实现的。然后有一些类(小明、小王)继承了该“吃”接口,并要具体实现小明、小王的细嚼慢咽、狼吞虎咽、津津有味方法。

1.如何定义接口

接口的定义与类的定义类似,只是类使用class关键字,而接口使用interface关键字,如:public interface Eat. 然后,需要在接口中定义一些方法、属性等。
注意:
①接口中只能定义方法、属性、事件、索引器或者这4类成员的组合,不能定义字段、运算符重载、实例构造函数和析构函数;
②接口中定义方法时不能添加访问修饰符,因为接口中方法默认为public,且也不能显示的添加public;
③接口中的所有成员都默认是公共的,因此都不能再使用访问修饰符。

2.接口的继承

接口的继承与类的继承方法是一样的,定义完接口后,类使用“:”,后接接口名即可继承该接口。例如:

//定义接口public interface Compare{    //声明方法,但不实现    int CompareTo(object other)    {    }} //定义类,并继承接口public classs Person : Compare{    private int age;    public int Age    {        get{return age;}        set{age = value;}    }    //实现接口中的方法    public int CompareTo(object value)    {        //若value中没有值,则返回1,表示当前对象比传入对象大        if (value == null)          {            return 1;        }        //若value有值,则强制把object类型转换为Person类型        Person otherPerson = (Person)value;        //把当前对象的Age属性与需要比较的对象的Age属性进行比较        if (this.Age < otherPerson.Age)        {            return -1;        }        else if (this.Age > otherPerson.Age)        {            return 1;        }        else            return 0;    }}

3.调用接口

在上面,我们定义了接口,并在类中继承了该接口,然后我们需要在Main中调用该接口,一种实现方法为先将类实例化,然后通过类实例“.”接口方法名(参数)来达到调用接口方法的目的。例如:

class Program{    static void Main(string[] args)    {        //类的实例化        Person p1 = new Person();        Person p2 = new Person();        p1.Age = 20;        p2.Age = 30;        //调用接口方法,对p1和p2的年龄进行比较        if (p1.CompareTo(p2) > 0)        {            Console.WriteLine("p1比p2大");        }        else if (p1.CompareTo(p2) < 0)        {            Console.WriteLine("p1比p2小");        }        else        {            Console.WriteLine("p1和p2一样大");        }         Console.Read();    }}

运行以上代码,结果为:
运行结果

显式接口:

在上面的接口实现方法中,使用的是隐式的接口实现方法,即在实现代码中没有指定实现哪个接口中的CompareTo方法。但是如果有多个接口,且每个接口中都定义了一个相同返回类型、相同名字的方法,则使用隐式接口实现会出现问题。因为程序无法判定调用的是哪个接口中的这个方法。例如:

//中文接口interface Chinese{    //声明接口方法    void Hello();}//英文接口interface English{    //声明接口方法    void Hello();}//Greeting类实现了两个接口public class Greeting : Chinese, English{    //隐式接口实现    public void Hello()    {        Console.WriteLine("你好");    }}//隐式接口的实现class Program {    static void Main(string[] args)    {        Greeting greeting = new Greeting();        //调用中文接口        Chinese ChineseGreeting = (Chinese)greeting;        greeting.Hello();        //调用英文接口        English EnglishGreeting = (English)greeting;        greeting.Hello();        Console.Read();    }}

运行以上代码,结果为:
运行结果
可以看到,不管调用的是哪个接口,程序调用的都是同一个方法实现,输出都为“你好”。

为了解决这个问题,我们需要使用显式接口来解决这种情况。显式接口的实现方法为:在类的方法中指明实现的是哪个接口的方法,并在调用接口时修改为接口实例调用即可。例如:
将以上代码的Greeting类实现修改为:

public class Greeting : Chinese, English{    //显式接口实现    void Chinese.Hello()    {        Console.WriteLine("你好");    }    void English.Hello();    {        Console.WriteLine("Hello");    }}

调用接口部分修改为:

ChineseGreeting.Hello();EnglishGreeting.Hello();

重新运行修改后的代码,结果为:
运行结果
可以看到,显式接口实现解决了命名冲突的问题。

注意:
①使用显式接口时,类方法实现中不能添加任何访问修饰符,因为成员默认为私有;
②使用显式接口时,因为成员默认为私有,不能通过类的对象进行访问,必须通过接口实例进行访问。

前面具体分析了隐式与显式接口实现方式两种情况,但何时需要使用哪种接口需要自行判断,判断方法为:
ⅰ.采用隐式接口实现时,类和接口都可以访问接口中的方法;而若采用显式接口实现方式,接口方法只能通过接口来完成访问,因为此时接口方法默认为私有。
ⅱ.当类实现单个接口时,通常使用隐式接口实现方式,这样类的对象可以直接去访问接口方法。
ⅲ.当类实现了多个接口,并且接口中包含相同的方法名称、参数和返回类型时,则应使用显式接口实现方式。即使没有相同的方法签名,在实现多个接口时,仍推荐使用显式的方式,因为这样可以标识出哪个方法属于哪个接口。

0 0