《随笔二十一》——C#中的 “ 接口 、 as 运算符”

目录

什么是接口

使用BCL中的接口IComparable 接口的示例 (269P)

声明接口 (272P)

实现接口 (273P)

接口和抽象类的相同点和不同点

接口是引用类型 (275P)

接口和 as 运算符 (276P)

实现具有重复成员的接口 (277P)

将类对象转换为多个其实现接口的引用 (279P)

显式接口成员实现 (281P)

访问显式接口成员实现 (283P)

派生成员作为实现 (280P)

接口可以继承别的接口 (283P)

不同类实现一个接口的示例


什么是接口


接口是一种引用类型,它指定一组函数成员,但不实现它们。所以只能类和结构来实现接口。

先看一个使用接口的程序示例:

namespace HelloWorld_Console
{
    interface IInfo  //声明接口
    {
        string GetName();
        string GetAge();
    }
    class CA: IInfo //声明一个类,该类实现了接口IInfo
    {
        public string Name;
        public int Age;
//注意, 在类中实现接口的成员函数,该成员函数必须是public的,不能是其它的访问修饰符,否则错误
        public string GetName()
        {
            return Name;
        }
        public string GetAge()
        {
            return Age.ToString();
        }
    }
    class CB: IInfo
    {
        public string First;
        public string Last;
        public double PersonsAge;
        public string GetName()
        {
            return First+ " "+Last;
        }
        public string GetAge()
        {
            return PersonsAge.ToString();
        }
    }
    class Program
    {
        static void PrintInfo(IInfo item)
        {
            WriteLine($"Name:{item.GetName()},Age: {item.GetAge()}");
        }
        static void Main(string[] args)
        {
            CA a = new CA() { Name = "huangchengtao ",  Age = 21 };
            CB b = new CB() { First = "huangchengjian ",  Last = "Doe", PersonsAge = 14 };
            //对象的引用能自动转换为 它们实现的接口的引用
            PrintInfo(a);
            PrintInfo(b);
            ReadKey();
        }
    }
}

我们不管传入什么样的类类型到函数PrintInfo ( )中,它都能正确的处理。

 


使用BCL中的接口IComparable 接口的示例 (269P)


先看一个代码示例:

 class Program
    {
       
        static void Main(string[] args)
        {
            var myInt = new[] { 20, 4, 5, 6, 7, 8, 9 };
            Array.Sort(myInt);
            foreach(var tt in myInt)
            {
                WriteLine(tt);
            }
            ReadKey();
        }
    }

输出结果为:
4
5
6
7
8
9
20

Sort方法在int数组上工作得很好, 但是我们不可以在自定义的类或结构中使用,因为是它不知道如何比较用于自定义的对象以及如何进行排序。    Array 类的Sort方法其实依赖于一个叫做IComparable的接口,它声明在BCL中,包含唯一的方法CompareTo。

下面的代码是IComparable的接口的声明:

public interface IComparable
{
   int ComparaTo(object obj); //该函数在接口中不能有实现
}

该函数的返回值有:

  • 负数值——当前对象小于参数对象;
  • 正数值  —— 当前对象大于参数对象
  • 零  —— 两个对象在比较时相等。

Sort使用的算法可以使用元素的 CompareTo 方法来决定两个元素的次序。int类型实现了 IComparable, 但是自定义的类或结构没有, 因此当Sort尝试调用自定义的类或结构不存在的CompareTo方法时会抛出异常。

 

  我们可以通过让类实现 IComparable 接口,来使 Sort 方法可以用于自定义的类或结构类型的对象。要实现一个接口,类或结构必须做两件事情:

  • 必须在基类列表后面列出接口名称;
  • 必须为接口的每一个成员提供实现。

下面看代码示例:

namespace HelloWorld_Console
{
    class MyClass : IComparable  // Class implements interface.
    {
        public int TheValue;
        public int CompareTo(object obj)    // Implement the method.
        {
            MyClass mc = (MyClass)obj;

            if (this.TheValue < mc.TheValue)
                return -1;

            if (this.TheValue > mc.TheValue)
                return 1;

            return 0;
        }
    }
    class Program
    {
        static void PrintOut(string s, params MyClass[] mc)
        {
            Console.Write(s);
            foreach (var m in mc)
                Console.Write("{0} ", m.TheValue);

            Console.WriteLine("");
        }
        static void Main(string[] args)
        {
            var myInt = new[] { 20, 4, 16, 9, 2 };

            MyClass[] mcArr = new MyClass[5];   // Create array of MyClass objs.
            for (int i = 0; i < 5; i++)     // Initialize the array.
            {
                mcArr[i] = new MyClass();
                mcArr[i].TheValue = myInt[i];
            }

            PrintOut("Initial Order: ", mcArr);           // Print the initial array.

            Array.Sort(mcArr);                            // Sort the array.
            PrintOut("Sorted Order:  ", mcArr);            // Print the sorted array.
            ReadKey();
        }
    }
}

输出结果为;

Initial Order: 20 4 16 9 2
Sorted Order:  2 4 9 16 20

注意:如果仅仅声明CompareTo方法是不够的, 必须实现接口,也就是把接口名称放在基类列表中。


声明接口 (272P)


 使用关键字 interface 来定义接口,语法为:

interface  myInterface
{
  //interface members
}

接口声明不能包含以下成员:

  • 数据成员
  • 静态成员
  • 常量
  • 析构和构造函数

接口声明只能包含如下类型的非静态成员函数的声明:

  • 方法
  • 属性
  • 事件
  • 索引器

 

  • 这些函数成员的声明不能包含任何实现代码, 而在每一个成员声明的主体后必须使用分号。
  • 按照惯例,接口名称必须从大写的I开始(比如ISaveable )。
  • 与类和结构一样,接口声明还可以分隔成分部接口声明。
  •  在默认情况下, 接口是内部的(internal)—— 即只有当程序集中的代码能够访问。    可以使用关键字 internal 写在  interface 的前
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值