首先介绍什么是抽象类?

抽象类用关键字abstract修饰的类就是叫抽象类,抽象类天生的作用就是被继承的,所以不能实例化,只能被继承。而且 abstract 关键字不能和sealed一起使用,因为sealed是不允许继承,这样就是抽象类的意义冲突了。

    public abstract class Test
{ }

  现在我们知道知道了抽象类长的什么样了,下面要知道抽象类是干嘛用的。顾名思义把对象共有的东西抽象出来。比如猫和和狗鸟等都有眼睛,都有嘴巴。那我们就可以抽象出一个动物类。把眼睛和嘴巴放到这这些公共的部分抽象到动物类里里面。用来对继承于动物类的子类进行约束。下次在有一个狗。只要继承于动物类那么狗必须实现眼睛和嘴巴。

Dog类 继承了 Animal抽象了。VS提示我们没有实现抽象类Animal类的两个方法。由此可以看出抽象类是对子类的约束。说白了。抽象类就是对子类的抽象,即将子类中的公共部分提取出来,放到一个特定的类中。抽象类是一份合约,用于为同一类型(这里类型不是指数据类型,而是逻辑上的划分,如人和猫都是动物)的子类提供约束。约束他们的公共部分。

现在来总结下抽象类。

1.抽象类的定义需要abstract关键字

2.抽象类的存在的意义就是被继承的。所以不能实例化,不能与sealed关键字一起用。

3.抽象类允许存在非抽象方法和抽象方法。

4.抽象类的抽象成员,子类必须实现。

在来看看接口,接口和抽象类很多概念相似。接口的创建要用到interface,接口出现的意义也是被继承。也不能与sealed关键字一起用

    public interface Animal
{
void Run();
void Say();
}

接口的和抽象类功能一样,也是抽象公共部分。

 从逻辑上与抽象类区分的话。总结成一句话。就是接口约束子类对象的行为。抽象类是将同一类型类的公共部分提取出来,进行约束。注意这里的同一类型不是数据类型而是逻辑上的,比如人和啊猫啊狗都是动物。

来总结下两者的区别

1.学过C#的都知道类只能单继承,接口可以多继承。这个就是抽象类和接口的第一个区别。

2.接口不能包含已经实现成员,但是抽象类是可以的

3.接口的成员默认1实现是public的,但是抽象类的成员可以被访问修饰修饰但是不能是私有的。

4.抽象类多用于约束对象的核心基础成员,接口对于用于约束子类的行为。比如类型有哪些行为(方法)。

5.接口成员如果变动的话,实现子类全部都要变动,抽象只有抽象成员变动了子类才要变动。

6.接口不允许定义字段,抽象允许定义字段,但是不允许定义抽象字段。

最有精华的两句话

  • 抽象类和接口都是一种约束,这种约束使我们的代码有更好的层次结构,特别是在多人协同开发时(若每个人都按照自己的习惯来,对整个开发团队而言,开发成本不知要提高多少)。

  • 抽象类是对相同类型(不是数据类型)子类公共部分的抽象(约束),接口是对能力的一种约束

抽象类 VS 接口

 

引言

接口和抽象类是面向对象编程(OOP, Object Oriented programming)中两个绕不开的概念,二者相似而又有所不同。接下来,我们来了解二者的概念并比较它们的异同。

什么是抽象类型?

抽象类是一种特殊的类,该类不能被实例化。抽象类的存在就是为了被继承,即抽象类可以被其它类继承但不能被实例化。那么,我们为什么需要一个无法被实例化的类呢?这样做的优点是,通过抽象类我们制定了一份强制所有子类必须遵守的合约,使所有子类有着一致的层次结构。抽象类提供了一种规范用于规定子类如何进行工作,子类可根据自身情况来重写抽象类中的抽象成员(及其它可被重写的成员)以满足自身需求。

抽象类作为一个基类,可以包含已实现的成员,同时应至少包含一个抽象成员,否则就没必要使用抽象类了。如果一个抽象类中仅仅包含抽象方法,那么这时抽象类就和接口很像了。

什么是接口?

接口中不能包含任何被实现的成员,即接口中只能包含成员的签名。如,没有方法体的方法、只包含访问器关键字(set、get)的属性等。和抽象类类似,接口也是一份合约。C#中,接口和抽象类的主要区别是,类可以实现多个接口,但只能继承一个(抽象)类。

比较异同

特征 接口 抽象类
是否支持多继承 支持 不支持
默认实现 接口中不能包含任何已实现的成员 抽象类中可以包含已实现(非抽象)的成员
访问修饰符 接口成员默认是公共(public)的,不再允许被任何访问修饰符修饰 抽象类成员可以被访问修饰符(不能是private)修饰
核心 VS 辅助 接口多用于定义(辅助性的)能力 抽象类多用于定义相同类型(这里类型不是数据类型的意思,解释见下文)子类所共有的一些特征
  若只提供一些方法上的约束,建议使用接口 如果子类属于同一类型,且具有相同的行为或状态,建议使用抽象类提供约束
寻找成员速度 相比抽象类较慢 相比接口更快
成员变动的影响 如果接口成员发生改动,则所有实现类都要进行改动 若向抽象类中添加非抽象成员,我们可以给该成员提供默认实现,这样子类就无需发生变动
允许包含的抽象成员 属性、方法、事件、索引器(这四类本质上都是方法) 属性、方法、事件、索引器
是否允许定义字段 不允许 不允许定义使用abstract修饰的字段

抽象类是对子类的抽象,即将子类中的公共部分提取出来,放到一个特定的类中。抽象类是一份合约,用于为同一类型(这里类型不是指数据类型,而是逻辑上的划分,如人和猫都是动物)的子类提供约束。
接口也是一份合约,但接口多用对能力的定义,即用于指定实现类能做哪些事儿。

人和猫,都属于动物这个大类,我们可以抽象出二者的公共部分。如,年龄、体重、吃、会叫(用于形容人不太友好)等作为一个抽象类的成员。

abstract class Animal
{
public abstract int Age { set; get; }
public abstract float Weight { set; get; }
public abstract void Call();
//默认实现
public virtual void Eat()
{
Console.WriteLine("猫粮......");
}
} class Person : Animal
{
public override int Age { set; get; }
public override float Weight { set; get; } public override void Eat()
{
Console.WriteLine("鱼香肉丝盖饭......");
} public override void Call()
{
Console.WriteLine("雷好啊......");
}
} class Cat : Animal
{
public override int Age { set; get; }
public override float Weight { set; get; } public override void Call()
{
Console.WriteLine("喵喵喵......");
}
}

那么,只要继承Animal类的类都应属于动物这个大类,汽车就不应该继承Animal类。
此外,人和猫相比,人会制作工具而猫不行,那么制作工具的技能就是人所特有的,这时可以定义一个接口提供对制作工具这项技能的约束,然后让Person类实现该接口。

interface ICreatTool
{
void CreateTool();
} class Person : Animal, ICreatTool
{
public override int Age { set; get; }
public override float Weight { set; get; } public override void Eat()
{
Console.WriteLine("鱼香肉丝盖饭......");
} public override void Call()
{
Console.WriteLine("雷好啊......");
} public void CreateTool()
{
Console.WriteLine("造台MAC......");
}
}

再如,人、车、猫三者都可以跑,那么也可以定义个接口用于对跑这项技能提供约束。

interface IRun
{
void Run();
} class Person : IRun
{
public void Run()
{
Console.WriteLine("11路公交......");
}
} class Cat : IRun
{
public void Run()
{
Console.WriteLine("四蹄奔腾......");
}
} class Car : IRun
{
public void Run()
{
Console.WriteLine("四轮......");
}
}

小结

用简单的话概括接口和抽象类的异同:

  • 抽象类和接口都是一种约束,这种约束使我们的代码有更好的层次结构,特别是在多人协同开发时(若每个人都按照自己的习惯来,对整个开发团队而言,开发成本不知要提高多少)。

  • 抽象类是对相同类型(不是数据类型)子类公共部分的抽象(约束),接口是对能力的一种约束。

C#知识点:抽象类和接口浅谈的更多相关文章

  1. 7.C#知识点:抽象类和接口浅谈

    知识点目录==========>传送门 首先介绍什么是抽象类? 抽象类用关键字abstract修饰的类就是叫抽象类,抽象类天生的作用就是被继承的,所以不能实例化,只能被继承.而且 abstrac ...

  2. java类,接口浅谈

    一般类,抽象类,接口的使用场景: 类;共同的特征和行为的抽取和封装 接口:标准,规范(功能的扩展)         需要对某个类进行功能的扩展,就让某个类实现这个接口,抽取出来称为接口   内部类: ...

  3. IActiveView 接口 - 浅谈

    IActiveView 和 IMap以其 Map, PageLayout之间的关系. 在ArcMap中, PageLayout 和 Map分别对应不同的视图: layout 和data view.在同 ...

  4. 浅谈Java中接口与抽象类的异同

    浅谈Java中接口与抽象类的异同 抽象类和接口这两个概念困扰了我许久,在我看来,接口与抽象类真的十分相似.期间也曾找过许许多多的资料,参考了各路大神的见解,也只能是简简单单地在语法上懂得两者的区别.硬 ...

  5. 浅谈我对C#中抽象类与接口的理解

    C#中的抽象类与接口有些相似,初学者很容易混淆,今天就让我来谈谈对二者的理解. 首先我们得明确二者的含义,分述如下: 如果一个类不与具体的事物相联系,而只是表达一种抽象的概念,仅仅是作为其派生类的一个 ...

  6. 浅谈java抽象类和接口

    第一次,写这个,没有把图片放上来,有兴趣的可以点击连接看原文 http://note.youdao.com/noteshare?id=aecbd52b9240f23c0954e8086b848a17 ...

  7. 浅谈C#中的接口和抽象类

    C#中接口为"其他方面互不相干"的类型提供公共的服务和特征:C#中class只支持但继承,使用接口却支持多继承,例如:C#中System.String是从System空间中的4个i ...

  8. 浅谈C#抽象类和C#接口

    原文地址:http://www.cnblogs.com/zhxhdean/archive/2011/04/21/2023353.html 一.C#抽象类: C#抽象类是特殊的类,只是不能被实例化:除此 ...

  9. 浅谈PHP面向对象编程(七、抽象类与接口)

    7.0 抽象类与接口 当定义一个类时,常常需要定义一些方法来描述该类的行为特征.但有时这些方法的实现方式是无法确定的,此时就可以使用抽象类和接口. 抽象类和接口用于提高程序的灵活性.抽象类是一种特殊的 ...

随机推荐

  1. Python3中,map()函数、filter()函数、reduce()函数的比较

    1.map(function,iterable):function为函数,或者lambda表达式,iterable是可迭代的序列,即对iterable中的每个item执行一遍function或者lam ...

  2. 【Canal】数据同步的终极解决方案,阿里巴巴开源的Canal框架当之无愧!!

    写在前面 在当今互联网行业,尤其是现在分布式.微服务开发环境下,为了提高搜索效率,以及搜索的精准度,会大量使用Redis.Memcached等NoSQL数据库,也会使用大量的Solr.Elastics ...

  3. 解决drf_yasg中的SwaggerAPI无法正确分组问题

    swagger是后台开发中很好用的交互式文档,Django原本的Django-Swagger已经停止维护了,现在一般用drf_yasg这个包来实现文档,它里面支持swagger和redoc两种,red ...

  4. java从零到变身爬虫大神

    刚开始先从最简单的爬虫逻辑入手 爬虫最简单的解析面真的是这样 import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import java. ...

  5. Visual Studio 2017版本15.9现在可用

    本文转自 https://blogs.msdn.microsoft.com/visualstudio/2018/11/19/visual-studio-2017-version-15-9-now-av ...

  6. C++统计单词数

    [题目描述] 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数.现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在 ...

  7. (转)@Autowired(required=false)注入注意的问题

    1.前言 在使用spring开发过程中,我们基本上都是使用@Autowired这个注解,用来注入已有的bean.但是有些时候,会注入失败.当我们加上参数(required=false)就能解决.今天整 ...

  8. swagger2配置详解

    1.写在controller上的注解 1.1 @Api 代码 @Api(tags = "用户相关接口", description = "提供用户相关的 Rest API& ...

  9. 如何在Linux上使用scp命令进行服务器之间的文件/目录传输

    1. 本地上传文件到远程: scp [local_file_path] [username]@[server_ip]:[remote_dir] 2. 本地上传目录到远程: scp -r [local_ ...

  10. Federated Optimization: Distributed Machine Learning for On-Device Intelligence

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! arXiv:1610.02527v1 [cs.LG] 8 Oct 2016 坐标下降法:https://blog.csdn.net/qq_ ...