《.NET程序员面试秘笈》----面试题10 接口和抽象类该如何取舍

简介: 【考点】抽象类的理解,抽象类和接口的区别。

本节书摘来自异步社区《.NET程序员面试秘笈》一书中的第1章,面试题10,作者: 张云翯, 更多章节内容可以访问云栖社区“异步社区”公众号查看。

面试题10 接口和抽象类该如何取舍

.NET程序员面试秘笈
【考点】抽象类的理解,抽象类和接口的区别。

【出现频率】

【解答】

接口和抽象类非常相似,两者都无法实例化,并且未实现部分都由派生类实现,其应用模型如图1.14所示。

结合图1.14可知,接口与抽象类的主要区别有以下几点:

(1)抽象类只能派生类,而接口可以派生类和结构。

(2)抽象类的派生类也可以是抽象类,即抽象成员在派生类中不一定被完全实现。而接口要求其派生类或结构必须完全实现其成员。

(3)抽象类可以包含已经实现的成员,可以包含字段,而接口只包含未实现的成员,不能包含字段。并且接口及所含成员必须为public访问级别。

(4)类只能继承一个抽象类,但可以继承(实现)多个接口。


a0722031850e81948dce02532cd48d8e880c4513

在具体的程序设计中,抽象类和接口的取舍应视程序的需要而定。抽象类可以用于归纳一组相似的、有共同特性的类,然后将这些类共同的成员提取到抽象类中,使抽象类作为这组类的基类。这样做到了代码的复用,不但节约了代码量,也减轻了维护的复杂度。然后将这组类中相似的方法或属性提取到抽象类中,成为抽象类的抽象成员,不提供具体实现,由这组类自己完成不同的实现。

说明:
抽象类的应用非常类似于网页制作中的CSS外部样式文件,大量风格相同的页面可以共用这个CSS文件,并且在页面中可以对部分CSS属性进行改写。
而接口是一组类的功能集合,也可以说是一组类的协定集合,这组类负责实现这些功能,可以说接口内含的成员都是抽象的。类可以实现多个接口,这样可将意图和实现分离,接口可以暴露给其他程序直接使用,并且可以很方便地进行功能的扩展。两者的应用对比如图1.14所示。

本例以Computer为接口,通过PCA类和PCB类实现该接口的功能。在ch01目录下新建一个程序文件,并命名为Abstract.cs,编写代码如程序1.11所示。


40386c1153cff9f47cfd6bdfcfc41ec3ef068f08


f121cc0e2bced730639f852c2268db57875d18ab

在命令行下编译Abstract.cs后,执行Abstract程序,其效果如图1.15所示。


(<a href=https://yqfile.alicdn.com/815a6d43015ae8430def24d12763e6fae330d9d7.png" >

本例代码中声明了名为Person的抽象类,类体中声明了两个抽象成员(1个方法和1个属性),Jacky类和Femal类继承了Person类。而Femal类只实现了抽象属性,所以Female必须仍然是抽象类,并且编写了Mariah类继承Female类,Mariah类实现了所继承的抽象方法。而Jacky类完全实现了Person类的抽象成员,所以Jacky类可以不是抽象类,可以创建实例。

程序运行时,创建Jacky类的实例a,并直接输出其_msg字段,还调用了a的getname方法,并访问了ismale属性。然后创建Mariah类的实例b,并进行相同的操作。从程序结果中可看出,Person抽象类的_msg字段为所有派生类的可复用字段,是派生类共同的部分。只有完全实现了Person类抽象成员的类才可以不是抽象类,如Jacky类,而没有完全实现的类如Female类仍然为抽象类。

【分析】

抽象类是一种用abstract关键字修饰的类,这种类仅用于被继承。类似于接口,抽象类无法创建实例,而类体可以声明多个未实现的抽象成员,这些成员由继承此类的派生类实现。其编写方法如以下代码所示:

abstract 类名称
{
 abstract 方法声明;
 abstract 属性声明;
 其他类成员声明及实现;
}

可见,抽象类的类体中可包含实现的成员,而未实现的成员为抽象成员。抽象方法或属性本身就是隐性的virtual,所以派生类实现抽象方法或属性必须使用override关键字。继承抽象类的类如果没有完全实现抽象成员,仍然只能是抽象类,即派生的非抽象类必须完全实现抽象成员。抽象类也可以实现接口,这时抽象类必须实现所有的接口成员,也可以将继承的接口成员映射至抽象成员,并由其派生类来实现。

说明:
抽象类的抽象成员不能使用virtual或static修饰。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
27天前
|
存储 算法 程序员
【Leetcode 程序员面试金典 01.01】判定字符是否唯一 —— 位运算|哈希表
可以使用哈希表或位运算来解决此问题:由题可知s[i]仅包含小写字母,int[26]即能表示字符的出现次数;
|
27天前
|
算法 程序员 索引
【Leetcode 程序员面试金典 02.08】 —— 环路检测 |双指针
我们可以使用双指针解决本题,由数学推导可知:a 的距离为(环长度的倍数 - b),即 tmp 指针从头节点走到环开头节点等于 slow 指针走到环开头节点的距离
|
27天前
|
Java 程序员
【Leetcode 程序员面试金典 05.01】插入 —— 位运算
位运算问题,只需要把 N 的 i 到 j 位都置 0 后再和 M 左移 i 位的结果进行按位或即可
|
1月前
|
人工智能 JavaScript 编译器
【利用AI刷面试题】AI:十道不常见的TypeScript面试题(二)
【利用AI刷面试题】AI:十道不常见的TypeScript面试题
|
1月前
|
存储 消息中间件 缓存
《吊打面试官》系列-Redis常见面试题(带答案)
《吊打面试官》系列-Redis常见面试题(带答案)
57 0
|
23天前
|
存储 Java
【面试问题】接口和抽象类有什么区别?
【1月更文挑战第27天】【面试问题】接口和抽象类有什么区别?
|
23天前
|
设计模式 消息中间件 缓存
2024年Java架构师面试宝典 图文并茂 10G面试题 请收藏
2024年Java架构师面试宝典 图文并茂 10G面试题 请收藏
79 1
|
30天前
|
存储 缓存 前端开发
【让AI为面试赋能系列】利用GPT回答网友的面试题1.0
【让AI为面试赋能系列】利用GPT回答网友的面试题1.0
|
30天前
|
人工智能 前端开发 JavaScript
AI为面试赋能:利用AI去回答网友的面试题(三)
AI为面试赋能:利用AI去回答网友的面试题
|
30天前
|
人工智能 缓存 JavaScript
AI为面试赋能:利用AI去回答网友的面试题(二)
AI为面试赋能:利用AI去回答网友的面试题

相关产品

  • 云迁移中心