第13章 接口

多继承(multiple inheritance)是指一个类从两个或多个基类派生的能力。

CLR不支持多继承,CLR只是通过接口提供了“缩水版”的多继承。

实现接口的类或结构必须实现接口定义中指定的接口成员。

    interface IEquatable<T>

    {

        bool Equals(T obj);

}

实现IEquatable<T>接口的任何类或结构都必须包含与该接口指定的签名匹配的Equals方法的定义。

    public class Car : IEquatable<Car>

    {

        public string Make { get; set; }

        public string Model { get; set; }

        public string Year { get; set; }

        public bool Equals(Car car)

        {

            if (this.Make == car.Make && this.Model == car.Model && this.Year == car.Year)

            {

                return true;

            }

            else

            {

                return false;

            }

        }

    }

IEquatable<T>的定义不为Equals提供实现,该接口仅定义签名。

类或结构可以实现多个接口,但是类只能继承单个类(抽象或不抽象)。

接口可以包含方法、属性、事件、索引器或这四种成员类型的任意组合。

接口成员会自动成为公共成员,不能包含任何访问修饰符。成员也不能是静态成员。

若要实现接口成员,实现类的对应成员必须是公共、非静态,并且具有与接口成员相同的名称和签名。

接口具有以下属性:

  • 接口类似于抽象基类。实现接口的任何类或结构都必须实现其所有成员。
  • 接口无法直接进行实例化。其成员由实现接口的任何类或结构来实现。
  • 接口可以包含事件、索引器、方法和属性。
  • 接口不包含方法的实现。
  • 一个类或结构可以实现多个接口。一个类可以继承一个基类,还可实现一个或多个接口。

13.1类和接口继承

从Object派生任何类实际都继承了以下内容:

  • 方法签名
  • 方法的实现(ToString, Equals, GetHashCode, GetType)

13.2定义接口

接口对一组方法签名进行了统一命名。接口还能定义事件,无参属性和索引器。所有这些本质上都是方法。但接口不能定义构造器方法。接口也不能定义任何实例字段。

C#禁止接口定义任何一种这样的静态成员。

在C#中是用interface关键字定义接口的。要为接口指定一个名称和一组实例方法签名。

对CLR而言,接口定义就像是一个类型定义。也就是说,CLR会为接口类型对象定义一个内部数据结构,同时可用反射机制来查询接口类型的功能。

和类型一样,接口可用在文件范围内定义,也可嵌套在另一个类型中定义。定义接口类型时,可指定你希望的任何可视性/可访问性(public, protect, internal等)。

接口成员会自动成为公共成员,不能包含任何访问修饰符。成员也不能是静态成员。

根据约定,接口类型名称要以大写I开头,目的是方便在源代码中辨认接口类型。

CLR支持泛型接口和在接口中的泛型方法。

13.3继承接口

以下代码展示了如何定义一个实现该接口的类型:

public interface IComparable<in T>

    {

        //接口成员不能包含任何访问修饰符,不能是静态成员,它会自动成为公共成员

        int CompareTo(T other);

    }

    public sealed class Point : IComparable<Point>

    {

        private Int32 m_x, m_y;

        //接口不能定义构造器方法,实现接口的类可以定义构造器方法

        public Point(Int32 x, Int32 y) 

        {

            m_x = x;

            m_y = y;

        }

        //和接口对应的成员必须是公共非静态的,和接口成员相同的名称和签名

        public Int32 CompareTo(Point other)

        {

            return Math.Sign(Math.Sqrt(m_x * m_x + m_y * m_y)

                - Math.Sqrt(other.m_x * other.m_x + other.m_y * other.m_y));

        }

        public override String ToString()

        {

            return String.Format("{0},{1}", m_x, m_y);

        }

    }

    public static class Program

    {

        public static void Main()

        {

            Point[] points = new Point[] { new Point(3, 3), new Point(1, 2) };

 

            if (points[0].CompareTo(points[1]) > 0)

            {

                Point tempPoint = points[0];

                points[0] = points[1];

                points[1] = tempPoint;

            }

            Console.WriteLine("Points from closest to (0,0) to farthest:");

            foreach (Point p in points)

                Console.WriteLine(p);

        }

    }

C#编译器要求将用于实现一个接口的方法标记为public。

编译器会将实现接口的方法标记为virtual和sealed。

posted @ 2016-06-26 18:05  Chris_在IT道路上前行  阅读(114)  评论(0编辑  收藏  举报