首先介绍什么是抽象类?

抽象类用关键字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. java_字节流、字符流的使用方法

    字节流 字节输出流[OutputStream] java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地.它定义了字节输出流的基本共性功能方法. p ...

  2. java_内部类、匿名内部类的使用

    内部类 将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类. 内部类的分类 成员内部类,类定义在了成员位置 (类中方法外称为成员位置) 局部内部类,类定义在方法内 成员内部类 ...

  3. C#LeetCode刷题之#811-子域名访问计数​​​​​​​(Subdomain Visit Count)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3814 访问. 一个网站域名,如"discuss.lee ...

  4. do...while循环语句(水仙花)

    #define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string.h>#include<stdlib.h&g ...

  5. Ubuntu 16.04 sudo免密码visudo sudoers设置

    使用sudo visudo调用nano对 /etc/sudoers 进行修改 $ sudo visudo 在想修改的对象最后加上 NOPASSWD: ALL 注意:在后面的设置会覆盖前面的设置

  6. 【USACO13DEC】 最优挤奶 - 线段树

    题目描述 FJ最近买了1个新仓库, 内含N 个挤奶机,1 到N 编号并排成一行. 挤奶机i 每天能产出M(i) 单位的奶.不幸的是, 机器装得太近以至于如果一台机器i 在某天被使用, 那与它相邻的两台 ...

  7. JavaScript设计模式之单例模式【惰性单例】

    在提高开发水平,往中高级前端工程师中,利用设计模式是必不可少的一条道路.掌握设计模式的思想远远比硬套重要,因为设计模式是一种思想,不局限于开发语言.但实际上由于语言的特性不同,往往在实现的时候会有不少 ...

  8. RocketMQ在windows环境下的安装(转)

    原博地址:https://www.jianshu.com/p/4a275e779afa 一.预备环境 1.系统 Windows 2. 环境 JDK1.8.Maven.Git 二. RocketMQ部署 ...

  9. NameNode和SecondaryNameNode(面试开发重点)

    NameNode和SecondaryNameNode(面试开发重点) 1 NN和2NN工作机制 思考:NameNode中的元数据是存储在哪里的? 首先,我们做个假设,如果存储在NameNode节点的磁 ...

  10. Ceph Luminous手动解决pg分布不均衡问题

    原文链接: https://www.jianshu.com/p/afb6277dbfd6 1.设置集群仅支持 Luminous(或者L之后的)客户端 具体命令: ceph osd set-requir ...