C#接口(interface)的理解

来源:互联网 发布:在线域名分析 编辑:程序博客网 时间:2024/05/16 16:18

        最近不忙,由于过去做的都是小型项目,个人开发,一直没太仔细研究过接口,只是一开始学习C#的时候看到过,当时一知半解,最近看了些项目,架构和设计模式,对于接口和oo有了更深理解,所以写下文章记录下来。只是一些个人的感悟和总结,如果有高手看到此文,还请指点!

        C#是面向对象的,即OO,C#中针对oo特点功能很多,比如多态,继承,封装,我就不套概念了。接口就是一种比较抽象的 面向对象的概念。

        初始的时候对于接口并不理解,确实初学者也不容易开始就用到接口,可能大部分实际的要学习数据库之类的,可是到了一定规模的项目 ,或者对于软件的架构有了一定概念,而不是一开始满足于写出功能的成就感,那么就会关注到接口,我对接口的兴趣与了解来源于别人的项目启发。下面总结一下接口的概念和好处:

        首先,个人理解,接口是一种规约,一种对于需要完成或者实现的对象的功能的抽象,它只定义一系列应该完成的功能规则,并不具体实现,所以很多初学者很迷惑,实现不了功能,我要它何用。但是,存在即是道理。个人认为,接口之所以作为一种规约,制定了规则却不实现,首先基于大型项目 ,团队合作之间的规范性开发要求。说白点,一个大型项目需要团队不同人员开发,架构师设计好框架,需要实现的类和功能之后,那么程序的骨架就有了,他不需要管如何实现的,那么程序开发人员需要去具体填充这个架构,实现这个架构的功能,为了更好更高效的去沟通实现,在一定的规则之下完成上面的工作,就需要对于类的功能和其他特性进行总体规范,实现人员只要管实现,这样有利于开发人员方便明确的实现架构师的设计,而没有任何歧义。

      其次,从接口的定义,具体类的实现和继承上面说,一个接口规定了一系列可继承他的类的普遍功能,那就对于继承类的实现有了一定约束,他需要实现接口所有定义的功能和特性,如果不能,那么就会编译报错,这样可以统一功能,让开发人员不会对于同一功能的定义有误差,说白了,就是开发人员们写不同的实现类,不会出现几个人分别写了同样功能而名称不同的函数。

        最后,我觉得最重要的一点,就是对于扩展性,安全性还有框架美观性能上面的作用了,我想大部分人比较关注与这点,所以写了个简单的例子:

        这个例子是个控制台程序,首先定义了类IAnimal,动物接口,动物是个整体的概念,动物分很多种,但是每种都不同,狗,猫,鸟又统称动物,他们有共同的特征和能力,吃、动、叫等等,那么我们的动物接口就要规定动物要有这些功能,会吃、会动、会叫,按照接口定义,IAnimal接口如下:

interface IAnimal

    {
        void Eat();
        void Bark();
        void Move();
    }

好了,动物的规定完成了,那么我们就要具体去看,我们要有什么动物,下面定义了狗和鸟两种类,他们继承与IAnimal接口,因为都是动物

 首先,是狗

class DogClass:IAnimal    {
        public void Eat()
        {
            Console.WriteLine("Dog eat bones!");
        }
        public void Bark()
        {
            Console.WriteLine("Dog bark:WangWang……");
        }
        public void Move()
        {
            Console.WriteLine("Dog Run……");
        }
   }

 class Bird:IAnimal
    {
        public void Eat()
        {
            Console.WriteLine("Bird eat bugs!");
        }
        public void Bark()
        {
            Console.WriteLine("Bird bark:ZhiZhi……");
        }
        public void Move()
        {
            Console.WriteLine("Bird fly……");
        }

    }

从上面的类可以看到,鸟和狗都分别实现了不同的动物应该有的能力,吃,动、叫

现在看似完成了,一般大家会想,我定义什么接口,就定义两个类,没有接口不是一样么,或者说  动物我不写接口,我写成抽象类 也是可以的,这就要从主程序的实现上说起了

主程序

  static void Main(string[] args)
        {
            IAnimal ianimal = new DogClass();
            ianimal.Eat();
            ianimal.Bark();
            ianimal.Move();
                       Console.WriteLine("Animal change!");

            ianimal = new Bird();
            ianimal.Eat();
            ianimal.Bark();
            ianimal.Move();
                      Console.WriteLine("IAnimal complete");

            Console.ReadLine();
        }

   上面之所以定义接口,然后去new不同的继承与接口的对象,原因在于工厂模式,没看过C#设计模式的可以去看看。

  如果我定义了两个类,那么现在主程序就要生命两个变量对象,现在很小的程序,无所谓,但是如果程序规模大了,那么就会很乱,而且重复的申请对象,分配内存如果没有单件模式,在一个大程序复杂的结构中是不合理,且有风险的,当然靠着GC 和CLR机制我们可以不太考虑垃圾回收问题。可是小小的性能影响总会让人不满意。

       那么要是定义了抽象类基类而不是接口呢?大家肯定知道 抽象类是不能实例化的,如果主程序后面需要判断实例化对象类型 ,那么我们没有办法向上面一样只声明一个变量而实现不同对象,具体我就不再说明,但是最主要在于,在大型项目中,随着需求变更,那么更改或者添加功能是很常见的,频繁的修改基类会影响后面所有继承它的类,造成的麻烦无法估量,而接口则没有这些限制,原因在于接口可以多继承,比如上面的程序,我需要实例的动物可以有play  玩的功能,那么我只要添加IPlay接口,只有玩一个功能

谁要玩,谁继承它就好了,现在修改,让狗有玩的功能 如下:

interface IPlay
    {
        void Play();
    }

class DogClass:IAnimal,IPlay
    {
        public void Eat()
        {
            Console.WriteLine("Dog eat bones!");
        }
        public void Bark()
        {
            Console.WriteLine("Dog bark:WangWang……");
        }
        public void Move()
        {
            Console.WriteLine("Dog Run……");
        }
        public void Play()
        {
            Console.WriteLine("Dog playing ball……");
        }
    }

我只需要狗,继承IPlay接口,实现玩就可以,鸟可以不管,这样我没有修改任何基础内容,而且随意的功能定义和添加不影响如鸟 这个类的实现和功能,

    IAnimal ianimal = new DogClass();
            ianimal.Eat();
            ianimal.Bark();
            ianimal.Move();
            DogClass dc = (DogClass)ianimal;
            dc.Play();

            Console.WriteLine("Animal change!");

            ianimal = new Bird();
            ianimal.Eat();
            ianimal.Bark();
            ianimal.Move();
          

            Console.WriteLine("IAnimal complete");

            Console.ReadLine();

主程序修改如上,狗现在可以玩了,鸟不可以玩,因为鸟没有继承玩的特性,我不需要它能玩,我就可以不管他,这样,所有功能的定义和修改只针对狗这个对象,而没有影响其它,这就是oo吸引人的地方,如果我动物没写成接口,而写成了抽象类,那么,玩这个功能我就要去修改基类,势必会影响鸟这个类的功能实现,同时也会对团队开发者造成歧义,说俗一点人家肯定会这么想(你tm加了个玩,那我开发的动物是不是让它玩啊,你倒是说清楚了,说清楚了……)这样团队需要反复沟通,效率大打折扣,而且如果实现类很多,那么改动不是一点两点了,复杂的结构里面,基础的改动,对于整体影响无法预计,说不定就造成了什么很变态且找不到的bug。

     对于接口的理解暂时就这么多,第一次写文章有些啰嗦,有些生涩,还请观看的高手们不要见怪,有不对的地方请提出来,一起讨论。

原创粉丝点击