问题出现:

我们在使用C#的抽象类和接口的时候,往往会遇到以下类似的问题,大致归纳如下:

(1)抽象类和接口有什么本质的区别和联系?

(2)什么时候选择使用抽象类,然啥时候使用接口最恰当呢?

(3)在项目中怎样使用才能使得项目更具有可维护性、扩展性?怎样将它和Struct,类紧密的结合,达到最终的双刃剑作用?

解决方案:

这也是我在学习抽象类和接口的时候遇到的问题,从我归纳的这三个问题,不难看出这也许是我们大多数程序员遇到问题的三个阶段,

第一阶段(基础概念):就象问题1一样,这部分人首先需要扫清基础概念的障碍,首先得懂得什么叫抽象类,什么叫接口?

然后了解抽象类和接口之间的区别和联系是什么?当然这可能需要一段时间去理解和实践,毕竟这些概念比较抽象,属于那种摸不着看不到的东西,当然最主要还是多练习,没事的时候做个Demo实例,把它们都使用一遍,在使用的过程中多想想为什么要这样用?这用有什么好处?能不能使用接口呢,如果不能,使用抽象类好处又在哪?这样可以加深对它们的理解,这也是我的一点点经验吧,呵呵!说了这么多,我还是把问题1总结一下,一是方便自己记,二是加深理解吧。

抽象类和接口的概念:其实这些概念在教科书和博客里基本上一大堆,前辈们总结的也很好了,但是可能在通俗、易懂方面有点晦涩难懂,我就翻译一下,加点陕西版的白话文,嘿嘿。

(1)抽象类:提供了一组派生类访问共享基类的公共方法;

抽象类的特性是:(1)抽象类既包括抽象方法,也可以包括方法的实现;(2)抽象类不能被实例化,也不能被密封;(3)抽象类中的抽象方法要么在派生类中实现,要么用派生抽象类继承(抽象派生类可以继承基类抽象方法的),如果要在派生类中实现 基类的抽象方法,必须使用override 修饰符;(4)抽象类属于单继承(这点属于所有类的同性,在这提一下)(5)抽象类是一族群的抽象,类似于 IS-A;

以上我如果说的还不是很清楚,给你个官网的关于抽象类的地址:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract

(2)接口:包含了一组虚方法的抽象类型;

接口的特性是:(1)接口中只包括虚方法的定义,只有声明定义,没有函数实现;(2)接口类中可以包括属性、事件、索引器等,但不能包括字段;(3)接口类属于多继承;(4)继承了接口的类必须全部实现接口的方法;

如果想了解官网关于接口的说明,给你一个地址:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface

抽象类和接口的区别和联系:

相同点:(1)都是不能直接实例化,只能通过继承方式去实现;

(2)都是对事物行为和对象的抽象,形成一定的设计模式;

不同点:

(1)接口支持多继承;抽象类不能实现多继承;

(2)接口包括方法、属性、事件、索引器,不能包括字段;抽象类可以包括字段,也可以包括方法的实现;

(3)接口可以支持回调,抽象类不支持回调

(4)接口可以作为值类型和引用类型基类,而抽象类只能作为引用类型的基类;

第二阶段(使用阶段):就象问题2一样,这部分人对基础有了一定的了解,但就是缺乏一定的实践,或许就是做个简单的Demo了事,那么什么时候用抽象类,啥时用接口呢?

分析第二个问题,我提出3点建议:

第一个建议,对基础概念不只是概念的记忆,要多练、多思,然后再多练、再多思,循环几次,直到熟烂于心;

第二个建议,尽量在自己的项目中使用这方面的知识,去使用它,你才能发现问题,解决问题,才会思考;

第三个建议,对自己使用过的抽象类和接口的项目的知识点进行总结和归纳; 
就什么时候使用抽象类和接口,我总结前辈的经验,给出以下几点,仅供参考:

(1)当设计的组件将来有多个版本的时候一般使用抽象类,例如用C#设计数据库DB,刚开始你可能使用的是sql server ,mysql,以后大型的项目可能要使用oracle,DB这种大型的数据库系统,那么我们在设计类的时候就设计一个抽象的基类DB,让它具有 数据的一些通用的属性和方法,属性:数据库的连接名,版本,数据库类型,数据库的通用方法:Open(),Close()方法等;

(2)当设计的组件同时支持通用的行为动作,可以考虑接口;例如鸟类,人类,车类都可以有声音,这时候可以设计接口,包含叫的函数行为,然后在各个具体的类中实现;

(3)在继承了接口的派生类或接口中,一旦该接口需要增加行为方法是个比较头疼的事情,必须所有的继承都必须实现它的方法,这个时候可以在派生类去实现一个新增的接口,来实现派生类的独特动作,举例说明:

/// <summary>
/// 实现一个爬行动物的动作接口
/// </summary>
interface IAnimalClimb
{
void Climb();
}

/// <summary>
/// 实现一个会叫的动物的动作接口
/// </summary>
interface ICry
{
void Cry();
}
/// <summary>
/// 实现一个动物抽象类
/// </summary>
public abstract class Animal
{
//动物的名字
public string Name { get; set; }
//动物的颜色
public string Color { get; set; }

//动物抽象类的共有方法

public abstract void Sleep();

public abstract void Breathe();
}

/// <summary>
/// 定义鸟类,通用方法是会飞
/// </summary>
public class Bird : Animal,ICry
{

public override void Sleep()
{
Console.WriteLine("Bird派生类继承了基类的Sleep()方法");
}

public override void Breathe()
{
Console.WriteLine("Bird派生类继承了基类的Breathe()方法");
}

//鸟类可以继承统一的接口动作,例如:叫
public void Cry()
{
Console.WriteLine("Bird派生类继承了接口ICry的叫的方法");
}
}

/// <summary>
/// 定义爬行动物类
/// </summary>
public class Snake : Animal, IAnimalClimb
{
public override void Breathe()
{
Console.WriteLine("Snake派生类继承了基类的Sleep()方法");
}

public override void Sleep()
{
Console.WriteLine("Snake派生类继承了基类的Sleep()方法");

}
//爬行动物可以继承统一的接口动物,例如:爬
public void Climb()
{
Console.WriteLine("Snake派生类继承了接口IAnimalClimb的爬的方法");
}
}
以上代码,只是说明问题,比较简单;
第三阶段(优化阶段):就象问题3一样,我们在做一个抽象类或者接口的时候首先考虑的是能用就行,结果就是定义的类或接口比较多,难以维护和扩展,或者就是类之间有交集,那怎么优化继承关系?怎样才能使得程序具有可维护性和扩展性呢?
我个人建议具备以下几个方面方可:
(1)要有扎实的基础知识和深厚的基础功底;
(2)要有一个多问、多思的心;对于抽象类和接口多问问,为什么不使用抽象类而要使用接口?为什么在这个地方使用接口合适?
(3)多看看前辈们是怎么设计接口和类的,这方面的资料网上搜搜不少;
(4)个人建议多看看设计模式这方面的知识,因为他们是前辈在设计时的经验和思想;
以上观点和说明,只是代表我个人的意见和建议,如有好的想法,大家可以相互交流,菜鸟会虚心听取大家的意见和建议。

原文地址:http://www.cnblogs.com/djzxjblogs/p/7587735.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

C#中的两把双刃剑:抽象类和接口相关推荐

  1. java中抽象接口_一篇文章让你彻底理解java中抽象类和接口

    相信大家都有这种感觉:抽象类与接口这两者有太多相似的地方,又有太多不同的地方.往往这二者可以让初学者摸不着头脑,无论是在实际编程的时候,还是在面试的时候,抽象类与接口都显得格外重要!希望看完这篇博客文 ...

  2. java中抽象类和接口的作用与区别

    抽象类与接口的区别 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstract ...

  3. 详细解析Java中抽象类和接口的区别

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

  4. 深入理解Java中的抽象类和接口

    对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候会以为它们可以随意互换使用, ...

  5. 【转】详细解析Java中抽象类和接口的区别

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

  6. java 抽象类与接口区别是什么_JAVA中抽象类与接口的区别,分别在什么情况下使用它们...

    在网上看到很多人问关于"抽象类与接口的区别",因此本人想通过自己多年对JAVA开发的经验来总结一下抽象类与接口的区别以及分别在什么情况下使用它们. 在Java语言中, abstra ...

  7. 详细解析Java中抽象类和接口的区别(很容易理解错)

    2007-09-28 12:17作者:doublel出处:论坛整理责任编辑:方舟 在Java语言中, abstract class 和interface是支持抽象类定义的两种机制.正是由于这两种机制的 ...

  8. Java中抽象类和接口

    一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有声明,而没有具体的实现.抽象方法的声明格式为: 1 abstract void fun(); 抽象方法必须用abst ...

  9. Java中抽象类和接口的区别(来源一)

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

最新文章

  1. 51js 的json编辑器
  2. Docker之HelloWorld篇
  3. 控制台应用程序的根目录
  4. IP暴露接口IP白名单设置
  5. c#进阶(4)—— Redis 用于消息队列的存储
  6. excel三维地图数据源引用无效_Excel函数公式应用的基础,数据源的引用,动图解释...
  7. Problem D: 链表的基本运算(线性表)
  8. MySQL 到底能不能放到 Docker 里跑?
  9. JavaScript随机数及随机字符串
  10. Atitit Elasticsearch6之elasticsearch5.x 新特性 目录 1.1. 其实,elasticsearch5.x 和 elasticsearch2.x 并不区别很大。 1
  11. 如何对 ABAP 数据库表通过 ABAP 代码进行更新和删除操作试读版
  12. matlab2016 win10,新手,win10电脑上面装matlab2016a还是b好呢?64位操作系统
  13. 对HashMap进行排序处理
  14. 自监督对比损失和监督对比损失的对比
  15. 别说你不知道光纤有这七种类型!
  16. 奇异矩阵和非奇异矩阵 行列式矩阵简单理解 代数意义 几何意义 行列式的定义: 二阶行列式的几何意义: 三阶行列式的几何意义: 行列式化为对角形的几何解释: 二阶行列式乘积项的几何意
  17. Visual Studio 2013 旗舰版正式版密钥
  18. spring boot的 banner
  19. 【设计模式】Unity3D 观察者模式
  20. mysql去重汇总_Mysql常用SQL汇总

热门文章

  1. cobbler工作流分析
  2. apache服务器搭建过程中需要注意到的一些问题
  3. 配置Tomcat的日志系统
  4. Java正则表达式获取网页所有网址和链接文字
  5. crontab定时任务中文乱码问题
  6. 也来谈谈这致命的手机充电器
  7. SQL Sever 性能调优
  8. 使用 dotnet format 格式化代码
  9. 微软面向初学者的机器学习课程:3.1-构建使用ML模型的Web应用程序
  10. Dotnet创建Linux下的Service应用