C#虚基类继承与接口的区别

来源:互联网 发布:js数组中添加对象方法 编辑:程序博客网 时间:2024/05/16 19:07

有一个月没有好好写过C#了,今天和朋友讨论起这些概念的东西,于是顺便找到一些资料,和大家分享。

定义新的数据类型以及这些新的数据类型进行相互操作的方法

定义方式:

 

  1. class Cat
  2. {
  3. }
  4. class Cat:object
  5. {
  6. }

 

C#中所有的类都是默认由object类派生来的,显示指定或者省略效果是一样的,所以上面的两个例子是完全相同的。

C#中类包括:抽象类、密封类、非抽象类

abstract:表示修饰的类不完整,也就是抽象类,只能用做基类。 在使用是不能直接实例化,

不能使用new运算符。

sealed:表示修饰的类不可派生,也就是密封类。

base:访问最近的基类,也就是当前类继承的类

 

  1. class Cat:Animal
  2. {
  3.   public void Cat()
  4.   {
  5.     base.Eat();
  6.   }
  7. }

 

以上例子中base代表Animal。

注意:base只能在类的内部使用。

接口

一个接口定义一个协定。接口可以看成是特殊的抽象类,但是又有所区别。

一个接口可以从多个基接口继承,而一个类或结构可以实现多个接口。

接口可以包含方法、属性、事件和索引器。接口本身不提供它所定义的成员的实现,而抽象类中可以提供定义成员的实现。

接口只指定实现该接口的类或结构必须提供的成员。

接口本质上是一种类

不过他与类的区分还是很明显的——不能实例化

他的精髓在于提供一些类共同的地方,而且能“多继承”

我们知道所谓对象其实是数据和方法的封装。接口的作用更多的是工程上的,一般上我们用他来封装通用的行为,来达到程序的多态。

不必用object的观点来统一接口,在我的感觉中,继承简化对象结构,增加代码重用,接口抽象行为。

1. 接口本质上是类吗

这个,要看你认为“类的本质是什么”了,过多纠缠于这个说法,很容易陷入文字之争,意义不大。

2. 接口和类有什么区别和联系,主要是联系

区别:

类的定义需要“实现”,接口的定义只需要“声明”;

类能实例化出一个对象,接口不能;

类只能单根继承,接口可以多根继承;

继承一个类,相当于借用了它已实现的功能,实现一个接口,相当于对外做了一个承诺;

……

联系:类可以“实现”接口

3. 接口是否具备类的特征

这要看你认为哪些是“类的特征”,hehe,比如,“编译后会生成一个 .class 文件”算不算特征……

4. 接口是否是Object

不是。但可以用一个接口型的变量来引用一个对象,而且,被引用的对象,说到底,一定是一个 Object。

1、纯虚类与接口不同的是,纯虚类可以包含一些实现

2、用纯虚类包含一些基本的功能或方法

3、用接口来定义客户端与组件之间的通讯方法

4、虚基类的实现的变化可能会影响派生类

5、使用接口要比使用继承具有更强的适用性

接口的一些特征;

不可以包含任何实现;没有构造方法;任何成员都隐式声明为public;

接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念!

而类是负责功能的具体实现!

在类中也有抽象类的定义,抽象类与接口的区别在于:

抽象类是一个不完全的类,类里面有抽象的方法,属性,也可以有具体的方法和属性,需要进一步的专业化。

但接口是一个行为的规范,里面的所有东西都是抽象的!

一个类只可以继承一个基类也就是父类,但可以实现多个接口

PS:接口除了规范一个行为之外,在具体项目中的实际作用也是十分重要的,在面向对象的设计原则以及设计模式的使用中,无不体现作为一个接口的使用好处,最直接的就是设计原则中OCP(开放封闭原则),我们使用接口,而不需要关心他的具体实现,具体实现的细节变化也无关客户端(使用接口的类)的使用,对与扩展是开放的,我们可以另写一个接口的实现来扩展当前程序,而不影响上层的使用,但对修改是封闭的,即我们不能够再去修改接口的定义,当然这个“不能够”是指在规范原则上不应该这么做!

接口的使用–多态的实现:

 

  1. public interface IPolimorphism()
  2. {
  3.    void Say();
  4. }

 

建立一个Class1.cs文件,定义两个类,扩展IPolimorfism:

 

  1. using System;
  2. using System.Windows.Forms;
  3. namespace NorthWind
  4. {
  5.   public class Red:IPolimorphism  //实现接口的方法
  6.   {
  7.       public void Say()  //不需要指定override关键字
  8.       {
  9.            MessageBox.Show("Red!");
  10.       }
  11.   }
  12.  
  13.   public class Yello:IPolimorphism
  14.   {
  15.       public void Say() //不需要指定override关键字
  16.       {
  17.            MessageBox.Show("Yello!");
  18.       }
  19.   }
  20.  
  21. }

 

另一个MainFrm.cs文件,应用程序入口处:

 

  1. using System;
  2. using System.Windows.Forms;
  3. namespace NorthWind
  4. {
  5. public class MainFrm : System.Windows.Forms
  6. {
  7.    [STAThread]
  8.    static void Main()
  9.    {
  10.        IPolimorphism red  = new Red();
  11.        red.Say();
  12.        IPolimorphism yello = new Yello();
  13.        yello.Say();
  14.    }
  15.  
  16. }
  17. }

 

  举个例子,有一个老汉,做了一个面饼,给了他的几个儿子,老大用这个饼,加上点馅,包一下,做成了包子,老二用这个面饼,在外面刷上油,撒上料,烤一烤,做成了土家烧饼,老三呢,胡乱做,在饼上抹上乱七八糟的东西,烤一烤,做成了披萨饼.基类和派生类的关系就是这样,基类提供了基本的实现,派生类就在上面添料,最终就成了每个人心中想要的饼.

  那接口的故事则不一样,老汉没有给众人面,老汉这回给儿子们画了一个饼的设计图,规定了这个饼的厚度,直径等等,然后把这个规格表发给儿子们了,儿子们拿着画的饼,各自按自己的想法去做了.

  两个故事的区别告诉我们,接口是一种规格,是一个统一的标准,在实际应用中,接口有两方法的作用.

  1,通过接口更容易表现设计,更容易沟通,而且接口是没有实现代码的,因此,定好接口,再写实现代码,就算设计上有变动,也可以通过接口轻易实现修改.而如果不用接口的话,你将直接去写类,好不容易实现了一个类的代码,如果设计上有少许的变动,就要去改代码.

  2.接口是写类的实现者看的,这好比建筑图纸是画给施工工人看的.

 

一、抽象类:

      抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。

二、接口:

      接口是引用类型的,类似于类,和抽象类的相似之处有三点:

       1、不能实例化;

       2、包含未实现的方法声明;

    3、派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);

       另外,接口有如下特性:

接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)。

      三、抽象类和接口的区别:

      1.类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类.而接口只是一个行为的规范或规定,微软的自定义接口总是后带able字段,证明其是表述一类类“我能做。。。”.抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中.

      2.接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;     

      3.一个类一次可以实现若干个接口,但是只能扩展一个父类     

      4.接口可以用于支持回调,而继承并不具备这个特点.     

      5.抽象类不能被密封。   

      6.抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的.

      7.(接口)与非抽象类类似,抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。但是,允许抽象类将接口方法映射到抽象方法上。   

      8.抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现。   

      9.好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。   

     10.尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知.(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则。   

     11.如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法.

      四、抽象类和接口的使用:

      1. 如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本。

      2.如果创建的功能将在大范围的全异对象间使用,则使用接口。如果要设计小而简练的功能块,则使用接口。

      3.如果要设计大的功能单元,则使用抽象类.如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。   

      4.抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。

形象化表示:

1.飞机会飞,鸟会飞,他们都继承了同一个接口“飞”;但是F22属于飞机抽象类,鸽子属于鸟抽象类。

2. 就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我可以给你个具体的铁门或木门(多态);而且只能是门,你不能说它是窗(单继承);一个门可以有锁(接口)也可以有门铃(多实现)。 门(抽象类)定义了你是什么,接口(锁)规定了你能做什么(一个接口最好只能做一件事,你不能要求锁也能发出声音吧(接口污染))。

原创粉丝点击