【面向对象】抽象类和接口的对比学习



背景:

《大话设计模式》最后的面向对象基础,介绍了很多基础性的知识。例如继承,多态,接口,抽象类等。学习过后有了一些自己的总结,于是就有了这篇博客。

猛一提起,接口和抽象类,大家也许模模糊糊有个印象,但是具体它们二者有什么区别,还是说不上来。

所以,为了更好的了解和区分二者,更好的在程序代码中应用。我们下面来看看,接口和抽象类,到底有什么区别。

 

抽象类:

举个栗子:

小狗,小猫,小猪都是小动物,这些可爱的动物们都会发出叫声,小狗是“汪汪汪”,小猫是“喵喵喵”,小猪是“哼哼哼”。

现在,要我们实例化一个小狗,我们可以想象到小狗的样子,也许是其二无比的哈士奇,也许是微笑天使萨摩耶,总之实例化小狗是没问题的。

但是要我们实例一个小动物,我们不知道这小动物是什么样子,就没有办法实例化“动物”。因为动物是一个抽象的名词,所以,我们完全可以考虑把实例化没有任何意义的父类,改成抽象类。再来想,小狗小猫的叫声方法是具体的,但是动物的叫声是挺抽象的,是没有意义的,所以动物的叫声,可以改为抽象方法。

 

 C#中,允许把类和方法声明为abstract,(abstract就是抽象的意思)即抽象类和抽象方法。

代码表示:

 

<span style="font-family:Comic Sans MS;font-size:18px;"> abstract class Animal
{
  ……
  Protected abstract string getShoutSound();
}
 </span>

特点:

1.抽象类不能被实例化。(实例化动物,没有意义)

2.抽象方法必须要被子类重写的,不被重写,抽象方法就没有意义啦。

3.如果一个类里存在抽象方法,无论这个类里是否还存在其它一般的方法,这个类必须得是抽象类。(扣上抽象方法的帽子,这个类必然定义为抽象类)

 

上面的抽象类,希望我解释的不那么抽象,下面我们继续看看“接口”的相关知识。

 

接口:

举个栗子:话说,元宵节了,小动物们元宵喜乐会,大家show各自的才艺的时候到了。

本命年的孙悟空孙大圣,他带来的节目是《大圣归来2——看我72变》;特地从任意门赶来的小叮当,带来的节目是《口袋魔术》;没有睡懒觉,从高老庄坐高铁早早来到的猪八戒,带来的节目是《猪猪侠的36计》。

这些拥有魔法可以变东西,技高一筹的动物们,掌握的可不止是普通动物“叫声”的技能了,普通动物是没有办法具备他们三只的特异功能的,也只有它们三只拥有变东西的方法,这些特定的方法封装成为一个集合,就是我们要了解的接口(interface)了。


来一张UML图,帮你更好理清关系。


                     


因为,接口封装的是特殊功能,所以接口就像“高冷挑剔”的公主。又一下特性:比如,接口不可以实例化,要实现接口的类,就必须实现接口里所有的方法和属性。

但是别看接口挑剔,她也有“善解人意、热心肠“的一面,因为一个类可以实现多个接口,多个类也可以支持相同的接口。因为,接口让用户和其它开发人员更容易理解其他人的代码,接口让代码充满了爱,所以”充满爱“的接口有一个命名标志——大写的“I”。大家使用接口的时候,不要忘记哦。

 

部分代码理解展示:


变东西接口代码表示:


<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">	Interface IChange    //声明IChange 接口,记得”I“
	{
		String ChangeThing(string thing);   //接口的方法ChangeThing,括号里的参数是一个字符串变量,返回值类型也是字符串
	}</span></span>



叮当猫类代码表示:(Cat类代码不再展示,大家可以自由发挥)

<<span style="font-family:Comic Sans MS;font-size:18px;">span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Microsoft YaHei UI;font-size: 16pt;"> </span><span style="font-family:Comic Sans MS;"><span style="font-size: 16pt;">class MachineCat:Cat,Ichange//</span><span style="font-size:24px;">叮当猫继承猫类,并且实现IChange接口。</span><span style="font-size: 16pt;">
{
      public MachineCat()
     :base()
     {
      }
 
      public MachineCat(string name)
     :base(name)
     {
      }
 
      public string ChangeThing(string thing)  //实现接口方法
     {
         return base.Shout()+"我有万能的魔法口袋,我可以变出:"+ thing;
      }
}</span></span><span style="font-family:Microsoft YaHei UI;font-size: 16pt;">
</span></span></span>


孙大圣和猴子类也不再展示,大家自行发挥~
      

客户端代码表示:

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;"><pre name="code" class="csharp"><span style="font-size:24px;"><span style="font-family:Comic Sans MS;">Private void button2_Click(object sender,EventArgs e)
{
	MachineCat mcat= new MachineCat("叮当");   //创建两个类的实例
	MonekyKing wukong=new Mokeyking("孙悟空");
	
	Ichange[] array =new Ichange[2];    //声明一个接口数组,分别将两类的实例赋值给数组。
	array[0]=mcat;
	array[1]=wukong;
	
	MessageBox.Show(array[0].ChangeThing("各种各样的东西!"));  //利用了面向对象的多态性,实现各自的ChangeThing
	MessageBox.Show(array[0].ChangeThing("五花八门的东西!"));
	
	
}</span>
</span></span></span>


 
    

 

运行结果:

点击"叮当"按钮,显示:我的名字叫叮当,喵喵喵,我有万能的口袋,我可变出各种各样的东西!

点解"孙悟空"按钮,显示:我的名字叫"孙悟空",吼吼吼,我会七十二变,我可变出五花八门的东西!

 

对比分析:

分别了解完抽象类和接口,我们最后来一个小总结,对比分析一下抽象类和接口。

从形态上来看:一个类只能继承一个抽象类,但是一个类可以实现多个接口。

抽象类

接口       

类整体的抽象

类局部行为的抽象(如果只关注行为抽象,接口也是抽象类)

继承抽象类,应用于相似的类(猫狗继承动物类)

行为跨越不同的类(飞机麻雀 超人都会飞,但是各属不同的类)接口和继承抽象类不冲突(超人继承人类,实现飞行的接口)

自底向上抽象,重构而来(猫狗公共特征泛化出父类动物)

自顶向下设计,对方法实现未知(对于动物们如何实现特异功能行为未知)

 

全文总结:

通过可爱的小动物了解抽象类和接口,我们会发现其实面向对象充满了乐趣,面向对象应用在我们的生活当中,用心观察生活,认真生活,我们会找到和面向对象更多更有趣的联系。PS:今天是元宵节,祝大家节日快乐~

【面向对象】抽象类和接口的对比学习_第1张图片

以上若有失误之处,望各路豪杰提点~

 

 

你可能感兴趣的:(面向对象,C#)