实现多态的方式——接口

3. 用接口来实现多态

  接口是一种规范,也是一种能力,当一个类要表现出某种能力的时候,一般都用接口来实现。

  声明接口的方式: 接口的名称一般以 I 开头,以able结尾。因为以able结尾的单词代表某种能力。

  [public] interface I .. able

  {   成员;  }

  

  接口的特点:

  1)、接口不能被实例化;也就是说,接口不能new(不能创建对象)

  2)、接口中的成员不能加“访问修饰符”,接口中的成员访问修饰符默认为public,不能修改。

  3)、接口中的成员不能有任何实现(“光说不做”,只定义了一组未实现的成员,这点和抽象类相同)

  4)、接口只能包含方法、属性、索引器、事件(后三者本质都为方法),不能有字段和构造函数。

  5)、接口不能去继承一个类,而类可以继承接口(接口只能继承于接口,可以继承多个接口;而类既可以继承接口,也可以继承类)

  6)、一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,语法上A必须写在IA前面。      class MyClass : A , IA {}   因为类是单继承的。

     class MyClass : A , IA , IB , IC {}
  7)、只要一个类继承了接口,这个类就必须实现接口中的所有成员。

  8)、子类实现接口的方法时,不需要任何关键字,直接实现即可。

  9)、接口存在的意义就是为了实现多态

  8)、当一个抽象类实现接口的时候,需要子类去实现接口。如果抽象类不想实现接口,就必须将该成员标记为abstract,交给子类去实现。

  9)、显示实现接口的目的:解决方法的重名问题。

     什么时候显示的去实现接口:当继承的接口与类中的方法,参数、返回值一模一样的时候,要显示的实现接口。

    class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person();
            //调用Person类的 Cooking()
            p.Cooking();  // I AM COOKING

            //声明接口类型去指向类的对象
            ICookingable ic = new Person();
            //调用接口的Cooking()
            ic.Cooking();  // 显示实现接口 Cooking
            Console.ReadKey();
        }
    }

    public class Person : ICookingable    
    {
        public void Cooking() 
        {
            Console.WriteLine("I AM COOKING");
        }

        //显示实现接口的目的是为了解决 方法重名的问题
        //在外面访问这个方法的时候,本质上访问的是接口的方法所以可以不用加public
        void ICookingable.Cooking() 
        {
            Console.WriteLine("显示实现接口 Cooking");
        }

        private int _time;
        int ICookingable.Time 
        {
            get { return _time; }
            set { _time = value; }
        }

        private int _age;
        //普通属性:有对应的私有字段
        public int Age
        {
          get { return _age; }
          set { _age = value; }
        }   
    }

    public interface ICookingable 
    {
        //默认访问修饰符为 public,但不能加 public来修饰 
        void Cooking();

        //接口里面可以包含属性,因为属性的本质是两个方法:get set
        //这里的属性被称为自动属性,因为这里没有与它对应的私有字段
        int Time
        {
            get;
            set;
        }
    }

    public interface ITestable 
    {
        void Test();
    }
    //接口可以继承接口
    public interface ITeaable : ITestable 
    {
        void Ttea();
    }

  什么时候使用接口来实现多态?

       几个类无共同的父类,但有一个或者若干个共同的能力。

    真正的狮子会吼,石头狮子不会吼,机器狮子会吼

    这里不能以真正的狮子作为父类,因为石头狮子是不会吼的;这三种狮子,都与一个能力有关,就是吼;只要写一个狮子吼的接口,让真正的狮子、机器狮子继承这个接口,石头狮子不继承这个接口就可以了。

        static void Main(string[] args)
        {
            //真正的狮子会吼,石头狮子不会吼,机器狮子会吼
            LionBark lb1 = new RealLion();
            lb1.Bark();
            LionBark lb2 = new MachineLion();
            lb2.Bark();
            Console.ReadKey();
        }

        public interface LionBark 
        {
            void Bark();    //狮子吼
        }

        public class RealLion : LionBark
        {
            void LionBark.Bark() 
            {
                Console.WriteLine("真正的狮子,吼");
            }
        }

        //由于石头狮子不会吼,所以不需要继承狮子吼这个接口
        public class Stonelion 
        {
            public void Bark() 
            {
                Console.WriteLine("我不会吼");
            }
        }

        public class MachineLion : LionBark 
        {
            void LionBark.Bark() 
            {
                Console.WriteLine("机器做的狮子也会吼");
            }
        }
    }
原文地址:https://www.cnblogs.com/lcxBlog/p/4886471.html