走进C# abstract,了解抽象类与接口的异同
前言:
最近在研究.NET Core的一些类库源码的时候发现在底层类库中使用了大量的抽象类,然而发现自己搬砖这么多年好像从来没有在项目中使用抽象类或者抽象方法去实现某个功能模块,并且对修饰符Abstract概念也只懂得一些皮毛(也就是面试的时候会问下其基本作用)。当然,咱们不懂就要去慢慢的学习了解,不能让这些不懂的技术和知识点一直困扰着我们。接下来就让我们一起去探索C# Abstract修饰符的作用,并且了解在什么场景下我们会使用到抽象类,从而提升我们项目的健壮性。
abstract修饰符:
基本概念:abstract修饰符指示要修改的东西有缺失或不完整的实现。
修饰范围:abstract修饰符可以用于修饰类、方法、属性、索引器(indexer)和事件。
抽象类:
public abstract class HttpRequest{}
抽象方法:
//todo:抽象方法不能提供实际的实现,因此没有方法主体(并且抽象方法只能够在抽象类中声明)
public abstract void ActionMethod();
抽象属性:
public abstract string ContentType { get; set; }
抽象索引器:
public string this[int index] => $"获取_{index}";
抽象事件:
//首先声明该事件的委托类型
public delegate void BoilerLogHandler(string status); // 基于上面的委托定义事件
public abstract event BoilerLogHandler BoilerEventLog;
抽象类与接口的异同:
抽象类的用途:
是一个能够提供给多个派生类共享的通用基类。
接口的用途:
接口提供了派生类应遵循的标准结构。
抽象类的基本特征:
1、抽象类是特殊的类,除了不能实例化(只能通过实例化继承抽象方法的派生类来获取抽象类中的成员)外,具有类的其他特性(可以单继承)。
2、抽象类可以定义抽象方法,抽象方法没有现实。
3、继承抽象类的类必须把里面的抽象成员(成员包括:方法,属性,索引器,事件)全部重写(orveride),抽象类除外。
接口的基本特征:
1、接口无法直接进行实例化。
2、一个类或结构可以实现多个接口。
3、实现接口的任何类或结构都必须实现其所有成员。
4、接口包含的成员只有方法,属性,索引器(有参属性),事件四种成员。
5、接口不能包含实例字段、实例构造函数或终结器。
6、默认情况下,接口成员是公共的,不能有其他的修饰符。
抽象类和接口的区别:
相同:
1、都可以被继承
2、都不能直接被实例化
3、都可以包含方法声明且都没有实现
4、派生类必须实现未实现的成员
不同点:
1、接口可以被多重实现,抽象类只能被单一继承。
2、接口可以用于支持回调,继承并不具备这个特点。
3、抽象类可以定义字段、方法、属性、事件、索引器的实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。
4、接口中的成员访问类型默认为公共的,不能有其他的访问修饰符修饰。
5、定义的关键字不一样,抽象类需要使用abstract,而接口则使用interface。
抽象类和接口的使用:
1、抽象类表共性(常应用在具有相同的行为和特征中),而接口则表规范(用于定义一种行为)。
2、抽象类主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。
3、如果要设计大的功能单元,则使用抽象类;如果要设计小而简练的功能块,则使用接口。
4、如果预计要创建组件的多个版本,则创建抽象类。接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。
5、如果创建的功能将在大范围的全异对象间使用,则使用接口;如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。
6、分析对象,提炼内部共性形成抽象类,用以表示对象本质,即“是什么”。为外部提供调用或功能需要扩充时优先使用接口。
7、好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。
具体实例如下:
实例一:就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我可以给你个具体的铁门或木门(多态);而且只能是门,你不能说它是窗(单继承);一个门可以有锁(接口)也可以有门铃(多实现)。 门(抽象类)定义了你是什么,接口(锁)规定了你能做什么(一个接口最好只能做一件事,你不能要求锁也能发出声音吧(接口污染))。
实例二:比如说我们一个班级有很多为同学,这些同学都有着各自的特长,爱好,穿衣打扮的风格,因此我们减少代码冗余可以定义一个通用的学生抽象类用来描述学生的身高,体重,姓名,爱好,特征等相关特征和行为的公共抽象类。
实例三:我们需要创建 “狗”、“猫”、“鱼”、“马”这些对象(类),我们可以说他们有一些共同的属性像嘴巴、尾巴、重量、颜色、大小等等一些共同的属性(properties),但是它们彼此的属性的形状是不同的(如嘴巴),在这种情况下,我们如果一个个去定义各自类似的属性是不是比较繁琐?如果用抽象类是不是很方便的给他们去继承。抽象类也有个更加好的地方,体现在“同质异像”就是实质相同实现形式不同的方法继承上,例如上面的狗、猫、马等的呼吸这个方法或者跑的速度的方法形式不同,我们这个是用定义一个抽象方法,让他们各自的类去实现它是不是很方便。“抽象”的意义正在于此。将共同的东西抽出来封装,但不实现只给继承。
总结:
通过对抽象类的深入理解发现原来在程序设计方面需要考虑优化的问题还是有很多很多的,抽象类和接口的选择就是一个很典型的例子。往往我们会图简单而去直接定义接口使用,却往往忽视了后期的软件的健壮性和可拓展性。在以后的开发中需要多思考这方面的问题。最后假如文章有什么需要补充或者不足的地方希望大家指正,谢谢。
参考资料:
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/abstract-and-sealed-classes-and-class-members
https://blog.csdn.net/lizhenxiqnmlgb/article/details/82346478
https://kb.cnblogs.com/page/41836/
走进C# abstract,了解抽象类与接口的异同的更多相关文章
- java 8中抽象类与接口的异同
1.java 8中抽象类与接口的异同 相同点: 1)都是抽象类型: 2)都可以有实现方法(以前接口不行): 3)都可以不需要实现类或者继承者去实现所有方法,(以前不行,现在接口中默认方法不需要实现者实 ...
- php抽象类和接口的异同【转】
1. 相同点: (1) 两者都是抽象类,都不能实例化. (2) interface 实现类及 abstract class 的子类都必须要实现已经声明的抽象方法. 2. 不同点: ...
- (转)PHP中的 抽象类(abstract class)和 接口(interface)
转自:http://blog.csdn.net/sunlylorn/article/details/6124319 一. 抽象类abstract class 1 .抽象类是指在 class 前加了 a ...
- 抽象类(abstract class)和 接口(interface)
PHP中的 抽象类(abstract class)和 接口(interface) 一. 抽象类abstract class 1 .抽象类是指在 class 前加了 abstract 关键字且存在抽象方 ...
- PHP中的 抽象类(abstract class)和 接口(interface)
抽象类abstract class 1 .抽象类是指在 class 前加了 abstract 关键字且存在抽象方法(在类方法 function 关键字前加了 abstract 关键字)的类. 2 .抽 ...
- 在谈PHP中的 抽象类(abstract class)和 接口(interface)
一. 抽象类abstract class 1 .抽象类是指在 class 前加了 abstract 关键字且存在抽象方法(在类方法 function 关键字前加了 abstract 关键字)的类. 2 ...
- php中抽象类与接口的概念以及区别
php里面的接口类,抽象类到底有什么用呢? 刚接触php的时候,觉得这个东西没什么用,其实这些东西还是有一定的作用的,下面我就简单的说说. 1.php 接口类:interface 其实他们的作用很简单 ...
- java基础知识回顾之抽象类和接口的区别
/* 抽象类和接口的异同点: 相同点: 都是不断向上抽取而来的. 不同点: 1,抽象类需要被继承,而且只能单继承. 接口需要被实现,而且可以多实现. 2,抽象类中可以定义抽象方法和非抽象方法,子类继承 ...
- Java:【面向对象:抽象类,接口】
本文内容: 抽象类 接口 抽象类与接口的异同 首发日期:2018-03-24 抽象类: 虽然已经有了父类,但有时候父类也是无法直接描述某些共有属性的,比如哺乳类和人类都会叫,而一般来说哺乳类这个父类并 ...
随机推荐
- [学习笔记] 树上倍增求LCA
倍增这种东西,听起来挺高级,其实功能还没有线段树强大.线段树支持修改.查询,而倍增却不能支持修改,但是代码比线段树简单得多,而且当倍增这种思想被应用到树上时,它的价值就跟坐火箭一样,噌噌噌地往上涨. ...
- Redis GEO 功能使用场景
本文来源:https://www.dazhuanlan.com/2020/02/05/5e3a0a3110649/ 背景 前段时间自己在做附近直播相关业务,其中有一个核心的点就是检索用户附近的主播,也 ...
- 在实际开发中Java中enum的用法
在日常项目的开发中,往往会存在一些固定的值,而且"数据集"中的元素是有限的. 例如:st_code// 一些状态机制:01-激活 02-未激活 03 -注册..等等 还有一特性 ...
- 原生JS实现下拉列表
1 <div class="list"> 2 <ul> 3 <li> 4 <a href="#">Web部< ...
- docker 和 k8s 调研总结
一. docker简介 环境配置 软件开发最大的麻烦事之一,就是环境配置.用户计算机的环境都不相同,你怎么知道自家的软件,能在那些机器跑起来? 用户必须保证两件事:操作系统的设置,各种库和组件的安装. ...
- python面试题-python相关
1. __new__.__init__区别,如何实现单例模式,有什么优点 __new__是一个静态方法,__init__是一个实例方法 __new__返回一个创建的实例,__init__什么都不返回 ...
- 【C语言高级编程】你见过长度为0的数组吗?管你信不信,看就完了!
一.什么是零长度数组 零长度数组就是长度为0的数组. ANSI C 标准规定:定义一个数组时,数组的长度必须是一个常数,即数组的长度在编译的时候是确定的.在ANSI C 中定义一个数组的方法如下: 类 ...
- 【C语言学习笔记】空间换时间,查表法的经典例子!知识就是这么学到的~
我们怎么衡量一个函数/代码块/算法的优劣呢?这需要从多个角度看待.本篇笔记我们先不考虑代码可读性.规范性.可移植性那些角度. 在我们嵌入式中,我们需要根据实际资源的情况来设计我们的代码.比如当我们能用 ...
- 【暑假集训】HZOI2019 Luogu P1006 传纸条 二三四维解法
写三次丢失两次,我谔谔,以后再不在博客园先保存我就去死 题目内容 洛谷链接 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学被安排坐成一个\(m\)行.\(n\ ...
- 【应用服务 App Service】App Service发生错误请求时,如何查看IIS Freb日志,从中得知错误所发生的模块,请求中所携带的Header信息
问题描述 在使用Azure App Service时候,我们有时候对 一些请求发生错误毫无头绪,能从错误代码中知道请求错误,但是更多的信息呢? 当我们需要更多的信息时候,通常有以下的一些方式来查找问题 ...