走进C# abstract,了解抽象类与接口的异同

简介: 走进C# abstract,了解抽象类与接口的异同

前言:

  最近在研究.NET Core的一些类库源码的时候发现在底层类库中使用了大量的抽象类,然而发现自己搬砖这么多年好像从来没有在项目中使用抽象类或者抽象方法去实现某个功能模块,并且对修饰符Abstract概念也只懂得一些皮毛(也就是面试的时候会问下其基本作用)。当然,咱们不懂就要去慢慢的学习了解,不能让这些不懂的技术和知识点一直困扰着我们。接下来就让我们一起去探索C# Abstract修饰符的作用,并且了解在什么场景下我们会使用到抽象类,从而提升我们项目的健壮性。

abstract修饰符:

基本概念:abstract修饰符指示要修改的东西有缺失或不完整的实现。

修饰范围:abstract修饰符可以用于修饰类、方法、属性、索引器(indexer)和事件。

抽象类:

publicabstractclass HttpRequest{}

抽象方法:

//todo:抽象方法不能提供实际的实现,因此没有方法主体(并且抽象方法只能够在抽象类中声明)

publicabstractvoid ActionMethod();

抽象属性:

publicabstractstring ContentType { get; set; }

抽象索引器:

publicstringthis[int index] => $"获取_{index}";

抽象事件:

//首先声明该事件的委托类型

publicdelegatevoid BoilerLogHandler(string status);


// 基于上面的委托定义事件

publicabstractevent 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),但是它们彼此的属性的形状是不同的(如嘴巴),在这种情况下,我们如果一个个去定义各自类似的属性是不是比较繁琐?如果用抽象类是不是很方便的给他们去继承。抽象类也有个更加好的地方,体现在“同质异像”就是实质相同实现形式不同的方法继承上,例如上面的狗、猫、马等的呼吸这个方法或者跑的速度的方法形式不同,我们这个是用定义一个抽象方法,让他们各自的类去实现它是不是很方便。“抽象”的意义正在于此。将共同的东西抽出来封装,但不实现只给继承。

总结:

  通过对抽象类的深入理解发现原来在程序设计方面需要考虑优化的问题还是有很多很多的,抽象类和接口的选择就是一个很典型的例子。往往我们会图简单而去直接定义接口使用,却往往忽视了后期的软件的健壮性和可拓展性。在以后的开发中需要多思考这方面的问题。最后假如文章有什么需要补充或者不足的地方希望大家指正,谢谢。

相关文章
|
6月前
|
达摩院 Linux API
阿里达摩院MindOpt求解器V1.1新增C#接口
阿里达摩院MindOpt求解器发布最新版本V1.1,增加了C#相关API和文档。优化求解器产品是求解优化问题的专业计算软件,可广泛各个行业。阿里达摩院从2019年投入自研MindOpt优化求解器,截止目前经历27个版本的迭代,取得了多项国内和国际第一的成绩。就在上个月,2023年12月,在工信部产业发展促进中心等单位主办的首届能源电子产业创新大赛上,MindOpt获得电力用国产求解器第一名。本文将为C#开发者讲述如何下载安装MindOpt和C#案例源代码。
212 3
阿里达摩院MindOpt求解器V1.1新增C#接口
|
6月前
|
IDE C# 开发工具
C#系列之接口介绍
C#系列之接口介绍
|
6月前
|
编译器 C# 开发者
C# 11.0中的新特性:覆盖默认接口方法
C# 11.0进一步增强了接口的灵活性,引入了覆盖默认接口方法的能力。这一新特性允许类在实现接口时,不仅可以提供接口中未实现的方法的具体实现,还可以覆盖接口中定义的默认方法实现。本文将详细介绍C# 11.0中接口默认方法覆盖的工作原理、使用场景及其对现有代码的影响,帮助开发者更好地理解和应用这一新功能。
|
1月前
|
C#
C# 接口(Interface)
接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。 接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。 接口使得实现接口的类或结构在形式上保持一致。 抽象类在某种程度上与接口类似,但是,它们大多只是用在当只有少数方法由基类声明由派生类实现时。 接口本身并不实现任何功能,它只是和声明实现该接口的对象订立一个必须实现哪些行为的契约。 抽象类不能直接实例化,但允许派生出具体的,具有实际功能的类。
46 9
|
2月前
|
C# 索引
C# 一分钟浅谈:接口与抽象类的区别及使用
【9月更文挑战第2天】本文详细对比了面向对象编程中接口与抽象类的概念及区别。接口定义了行为规范,强制实现类提供具体实现;抽象类则既能定义抽象方法也能提供具体实现。文章通过具体示例介绍了如何使用接口和抽象类,并探讨了其实现方式、继承限制及实例化差异。最后总结了选择接口或抽象类应基于具体设计需求。掌握这两者有助于编写高质量的面向对象程序。
116 5
|
3月前
|
API C# 数据库
SemanticKernel/C#:实现接口,接入本地嵌入模型
SemanticKernel/C#:实现接口,接入本地嵌入模型
83 1
|
3月前
|
C#
C# 面向对象编程(三)——接口/枚举类型/泛型
C# 面向对象编程(三)——接口/枚举类型/泛型
33 0
|
6月前
|
前端开发 API C#
C# 接口
C# 接口
43 1
|
6月前
|
程序员 C#
C#抽象类和抽象方法详解
C#抽象类和抽象方法详解
62 0
|
6月前
|
C# 索引
C#学习相关系列之abstract和virtual用法
C#学习相关系列之abstract和virtual用法