文章概述
- 背景
- 问题
- 答案
- 概括
背景
以下是最流行的 OOP面试问题和答案的列表。这些 OOPS 面试问题适用于初学者和专业 C# 开发人员。
问题
- 什么是对象?
- 什么是封装?
- 什么是抽象?
- 什么是继承?
- 哪些是访问说明符?
- 如何在 C# 中实现多重继承?
- 私有类成员是否从派生类继承?
- 什么是多态?
- 什么是方法重载?
- 何时以及为何使用方法重载?
- 什么是方法覆盖?
- 什么是构造函数?
- 描述与构造函数相关的一些关键点。
- 什么是私有构造函数?
- 你能在 C# 中创建一个具有私有构造函数的类对象吗?
- C# 中的私有构造函数有什么用途?
- C# 中的静态构造函数有什么用途?
- 析构函数是什么?
- 什么是命名空间?
- C# 中的 Virtual、Override 和 New 关键字是什么?
- C# 中的 Struct 和 Class 有什么区别?
- 什么是接口?
- 为什么在 C# 中使用接口?
- 什么是隐式接口实现?
- 什么是显式接口实现?
- 什么是抽象类?
- 详细描述抽象类。
- 抽象和封装有什么区别?
- 抽象类可以在 C# 中被密封吗?
- C# 中抽象类可以有构造函数吗?
- 你能在 C# 中将抽象方法声明为私有的吗?
- C# 中抽象类可以有静态方法吗?
- 抽象类是否支持多重继承?
- 抽象类必须只有抽象方法。这是对还是错?
- 什么时候使用抽象类?
- 为什么抽象类不能被实例化?
- 您可以在抽象类中定义哪些类型的成员?
- 什么是运算符重载?
- 是否有可能在 C# 中限制对象创建?
- 你能在 C# 中继承 Enum 吗?
- 是否可以使用接口实现方法扩展?
- 一个方法可以一次返回多个值吗?
- 什么是 Constant?
- 什么是只读?
- 什么是静态?
- 什么是静态只读?
- “this” 可以在静态方法中使用吗?
- .Net 中的设计模式是什么?
- 设计模式有哪些类型?
- 使用设计模式的主要好处是什么?
- 静态类和单例实例有什么区别?
- 你能序列化 Hashtable 吗?
- 为什么单例模式被认为是反模式?
- C# 中的封装和数据隐藏是什么?
- C# 中的 Yield 关键字有什么用途?
- 如何在 C# 中一次捕获多个异常?
- C# 中的 IDisposable 接口有什么用途?
- C#.net 中的属性是什么?
- 什么是访问器?
- 什么是Partial部份类?
- 什么是Sealed 密封类?
- 什么是密封方法和属性?
- 如何在 C# 中从派生类调用基类构造函数?
- 什么是基本关键词?
- 三层架构有什么好处?
- 设计模式和架构模式有什么区别?
- C# 中的构造函数链是什么?
- 这和 C# 中的 base 有什么区别?
1.什么是对象?
- 类或结构定义就像一个蓝图,指定了该类型可以做什么。
- 对象基本上是已根据蓝图分配和配置的一块内存。
- 一个程序可以创建同一类的多个对象。
- 对象也称为实例,它们可以存储在命名变量中,也可以存储在数组或集合中。
2.什么是封装?
封装是将数据成员和成员函数绑定到单个单元的过程。
3.什么是抽象?
抽象是隐藏实现细节并显示基本特征的过程。
4.什么是继承?
继承是从已经存在的类派生新类的过程。
5.什么是访问说明符?
有 5 个访问说明符,
- Public 公共对象可以在类的外部通过对象引用来访问。
- Private 只能通过成员函数在类内部访问。
- Protected 可以像 private 一样,但也可以通过成员函数在派生类中访问。
- Internal 在程序集内部可见。可通过对象访问。
- Protected Internal 可以通过对象在程序集内部可见,也可以通过成员函数在程序集外部的派生类中可见。
6. 如何在 C# 中实现多重继承?
使用接口,您可以在 C# 中实现多重继承。
7. 私有类成员是否从派生类继承?
- 的,私有成员也在派生类中被继承,但我们将无法访问它们。
- 尝试访问派生类中的私有基类成员将报告编译时错误。
8.什么是多态?
当一条消息能够以不同的方式处理时,这就称为多态性。
- 多态性有多种形式。
- 多态性有两种类型。
编译时多态性也称为重载
运行时多态性也称为覆盖
9.什么是方法重载?
在类中创建具有相同名称但具有不同参数和不同类型的多个方法称为方法重载。
10.何时以及为何使用方法重载?
- 当您希望某个类能够执行某项操作,但对于执行该任务的方法需要提供的信息却有多种可能时,就必须使用方法重载。
- 当您需要几个采用不同参数但在概念上执行相同操作的方法时,您应该考虑重载方法。
11.什么是方法覆盖?
- 覆盖意味着在不改变签名的情况下改变方法的功能。
- 您可以通过在派生类中创建类似的方法来覆盖基类中的方法。
- 这可以通过使用 virtual/override 关键字来实现。
- 基类方法必须用 virtual 关键字标记,并且可以使用 override 关键字在派生类中覆盖它。
- 派生类方法将完全覆盖基类方法,即,当您引用通过强制转换派生类对象创建的基类对象时,将调用派生类中的方法。
12.什么是构造函数?
- 构造函数是类的一种特殊方法,在创建类的实例时会自动调用。
- 构造函数的主要用途是在创建类的实例时初始化类的私有字段。
- 当你在类中没有创建构造函数时,编译器会自动在类中创建一个默认构造函数。
- 默认构造函数将类中的所有数字字段初始化为零,并将所有字符串和对象字段初始化为空。
13. 描述有关构造函数的一些关键点。
- 一个类可以有任意数量的构造函数。
- 构造函数没有任何返回类型,甚至没有 void。
- 静态构造函数不能是参数化构造函数。
- 在一个类中,只能创建一个静态构造函数。
- 构造函数有 5 种类型,
默认构造函数
参数化构造函数
复制构造函数
静态构造函数
私有构造函数
14.什么是私有构造函数?
- 私有构造函数是一种特殊的实例构造函数,仅用于包含静态成员的类中。
- 如果一个类有一个或多个私有构造函数而没有公共构造函数,那么其他类就不允许创建该类的实例,这意味着您既不能创建该类的对象,也不能被其他类继承。
- 创建私有构造函数的主要目的是当类的每个成员都是静态时限制该类被实例化。
15. 在 C# 中可以使用私有构造函数创建类的对象吗?
不可以,具有私有构造函数的类的对象不能从类的外部实例化。
16. C# 中的私有构造函数有什么用途?
- 它用于停止某个类的对象创建。
- 它在 Singleton 类中使用。
- 它用于阻止类被继承。
- C# 中的静态构造函数有什么用途?
- 静态构造函数是一种特殊的构造函数,在创建类的第一个对象之前被调用。
- 它用于初始化任何静态数据或执行只需执行一次的特定操作。
- 静态构造函数的执行时间尚不清楚。但它肯定是在第一个对象创建之前——可能是在加载程序集时。
18.什么是析构函数?
- 当对象最终被销毁时,会自动调用析构函数。
- 析构函数的名称与类的名称相同,并以波浪符号 (~) 为前缀。
- 析构函数用于释放动态分配的内存并释放资源。
19.什么是命名空间?
命名空间允许创建一个系统来组织代码。
20. C# 中的 Virtual、Override 和 New 关键字是什么?
- 虚拟用于修改基类中声明的方法、属性、索引器或事件,并允许在派生类中重写它。
- 重写用于将基类的虚拟/抽象方法、属性、
索引器或事件扩展或修改到派生类中。 - New 用于将基类的方法、属性、索引器或事件隐藏到派生类中。
21. C# 中的 Struct 和 Class 有什么区别?
Struct 和 Class 都是用户定义的数据类型。
区别 | Struct | Class |
---|---|---|
类型 | 一种类型 | 一个引用类型 |
继承自 | 继承自System. Value | 继承自System. Object |
用于 | 通常用于较少量的数据 | 通常用于大量数据 |
继承至 | 不能被继承到其他类型 | 可以被其他类继承 |
抽象 | 不能是抽象的 | 可以是抽象类型 |
new 关键字 | 不需要用 new 关键字创建对象 | 不能使用 new 关键字来使用类的对象 |
默认构造函数 | 无权创建任何默认构造函数 | 可以创建默认构造函数 |
22.什么是接口?
- 接口看起来像一个类,但它没有实现。
- 它唯一包含的是事件、索引器、方法和/或属性的声明。
- 接口仅提供声明的原因是它们被结构和类继承,而结构和类必须为声明的每个接口成员提供一个实现。
23.为什么在 C# 中使用接口?
- 接口在 C# 中主要用于,
可扩展性
实现隐藏
使用接口访问对象
松耦合
24.什么是隐式接口实现?
- 实现接口成员最常规或最明显的方法。
- 不必指定成员的接口名称并隐式实现。
25.什么是显式接口实现?
- 实现接口成员的另一种方法。
- 需要指定成员的接口名称。
- 显式实现的约束是,不能使用类实例访问显式实现的成员,而只能通过接口的实例来访问。
26.什么是抽象类?
- 抽象类是一种特殊的类,不能被实例化。
- 那么,问题是为什么需要一个不能实例化的类?
- 抽象类只能被子类化(继承)。
- 换句话说,它只允许其他类从它继承但不能实例化。
- 其主要优点是它为所有子类强制实施某些层次结构。
- 简单来说,它是一种强制所有子类遵循相同的层次结构或标准的合同。
27.详细描述抽象类。
- 不能创建抽象类的对象。
- 抽象类与抽象类之间可以进行继承。您不需要将基抽象类的抽象方法实现到派生抽象类中。可以稍后在具体类中实现它。
- 抽象类永远不能是密封的或静态的。
- 抽象类可以有抽象方法也可以有非抽象方法。
- abstract 关键字可与类、方法、属性、索引器和事件一起使用。
- 抽象成员只能在抽象类内部声明。
- 抽象成员不能是静态的或私有的。
- 抽象方法不能被标记为虚拟。
- 一个具体类不能继承多个抽象类,换句话说,不可能实现多重继承。
- 如果没有抽象类,就无法实现模板方法模式。
28.抽象和封装有什么区别?
- 封装就是包装,它只是隐藏属性和方法。
- 封装用于将代码和数据隐藏在单个单元中,以保护数据免受外界侵害。
- 类是封装的最好例子。
- 抽象是指仅向目标用户显示必要的细节。
29. C# 中抽象类可以被密封吗?
- 不可以,抽象类不能是密封类。
- 因为 sealed 修饰符阻止类被继承,而 abstract 修饰符要求类被继承。
30. C# 中抽象类可以有构造函数吗?
是的,在 C# 中抽象类可以有一个构造函数。
31. 在 C# 中可以将抽象方法声明为私有的吗?
不可以。抽象方法在 C# 中不能是私有的。
32. C# 中抽象类可以有静态方法吗?
是的,在 C# 中抽象类可以有静态方法。
33. 抽象类支持多重继承吗?
不,抽象类不支持多重继承。
34. 抽象类必须只有抽象方法。对还是错?
错误。抽象类可以同时具有抽象方法和非抽象方法。
35. 什么时候使用抽象类?
当您有要求时,您的基类应该提供某些方法的默认实现,而其他方法应该被子类覆盖,那时您必须使用抽象类。
36.为什么抽象类不能被实例化?
- 因为它还没有完全实现类,所以它的抽象方法无法执行。
- 如果编译器允许我们为抽象类创建对象,那么您可以使用该对象调用抽象方法,而该方法在运行时无法由 CLR 执行。
- 因此,为了限制抽象方法的调用,编译器不允许您实例化抽象类。
37. 在抽象类中可以定义哪些类型的成员?
您可以定义所有静态和非静态成员,包括属性、字段、索引器以及抽象方法。
38.什么是运算符重载?
- 重载运算符是具有特殊名称的函数,即关键字 operator 后跟所定义的运算符的符号。
- 与任何其他函数类似,重载运算符具有返回类型和参数列表。
39. 是否可以在 C# 中限制对象创建?
是的,可以使用以下命令来限制 C# 中的对象创建,
- 抽象类
- 静态类
- 私有或受保护的构造函数
40. 在 C# 中可以继承 Enum 吗?
- 不,您不能在 C# 中继承 Enum。
- 因为枚举默认是密封的。所以您无法继承它们。
41.是否可以使用接口实现方法扩展?
- 是的,可以使用接口实现方法扩展。
- 大多数 LINQ 都是围绕接口扩展方法构建的。
- 接口实际上是扩展方法发展的驱动力之一。
- 由于它们无法实现任何自己的功能,因此扩展方法是将实际代码与接口定义关联的最简单方法。
42. 一个方法可以同时返回多个值吗?
是的,在 C# 中,方法可以通过以下方式一次返回多个值。
键值对
Ref 或 Out 参数
结构或类
元组
43.什么是常数?
- 常量在 C# 中被称为“const”关键字。
- 它也被称为不可变值。
- 这些在编译时是已知的,并且在运行时不会像应用程序生命周期内的任何函数或构造函数那样改变它们的值,直到应用程序运行。
44.什么是只读?
- Readonly 在 C# 中被称为“readonly”关键字。
- 它也被称为不可变值。
- 它们在编译和运行时是已知的,并且在应用程序运行之前的整个应用程序生命周期中都不会像任何函数那样在运行时改变它们的值。
- 当我们用“new”关键字调用构造函数时,你可以通过构造函数测定它们的值。
45.什么是静态?
- static 关键字用于指定静态成员。
- 这意味着静态成员对于所有对象来说都是通用的,并且它们不会与特定对象绑定。
- 静态关键字可与类、字段、方法、属性、运算符、事件和构造函数一起使用
- 但是,静态不能与索引器、析构函数或类以外的类型一起使用。
- 关于静态关键字的要点。
如果将 static 关键字应用于类,则该类的所有成员都必须是静态的。
静态方法只能访问同一个类的静态成员。
静态属性用于获取或设置类的静态字段的值。
静态构造函数不能被参数化。
访问修饰符不能应用于静态构造函数。因为它始终是一个公共默认构造函数,用于初始化类的静态字段。
46.什么是静态只读?
- 静态 Readonly 类型变量值可以在运行时或编译时分配,并且可以在运行时更改。
- 这样的变量的值只能在静态构造函数中改变,不能进一步改变。
- 它在运行时只能改变一次。
47. 静态方法中可以使用“this”吗?
- 不可以,“this”不能在静态方法中使用。
- 因为关键字“this”返回对包含它的类的当前实例的引用。
- 静态方法(或任何静态成员)不属于特定实例。
- 它们存在时无需创建类的实例,并且使用类名而不是实例进行调用,因此您不能在静态方法体中使用 this 关键字。
48. .Net 中的设计模式是什么?
- 面向对象世界中的设计模式是针对实际应用程序开发中反复出现的常见软件设计问题的可重用解决方案。
- 它是如何在多种情况下使用的解决问题的模板或描述。
49. 设计模式有哪些类型?
- 创建模式:主要处理对象和类的创建。
- 结构模式:它处理类和对象组合。
- 行为模式:它处理类和对象的通信。这意味着它们关注的是类和对象之间的通信。
50. 使用设计模式的主要好处是什么?
- 它们为开发人员提供了一系列经过尝试和测试的解决方案。
- 它们与语言无关,因此可以应用于任何支持面向对象的语言。
- 它们有助于交流,因为它们有详实的记录,如果没有记录的话还可以进行研究。
- 它们已经被广泛使用,有着良好的业绩记录,从而降低了项目的技术风险。
- 它们具有高度的灵活性,几乎可以用于任何类型的应用程序或领域。
51.静态类和单例实例有什么区别?
- 在 C# 中,静态类不能实现接口。虽然单例类需要实现接口以应对某些业务原因或 IoC 目的,但您可以在不使用静态类的情况下使用Singleton 模式。
- 您可以克隆Singleton的对象,但是不能克隆静态类对象。
- 单例对象存储在堆中,但静态对象存储在堆栈中。
- 单例可以延迟或异步初始化,而静态类通常在首次加载时初始化。
52. 你能序列化Hashtable吗?
- 不,您不能序列化 Hashtable。
- 因为.NET Framework不允许序列化任何实现IDictionary接口的对象。
53.为什么单例模式被认为是反模式?
- 单例模式在单元测试中不太好处理。你无法控制它们的实例化,而且它们可能会在调用过程中保留状态。
- 分配给 Singleton 的内存无法释放。
- 在多线程环境中,对单例对象的访问可能必须受到保护(例如通过同步)。
- 单例促进类之间的紧密耦合,因此很难测试。
54. C# 中的封装和数据隐藏是什么?
- 封装是向类外部隐藏成员的过程,它是使用访问说明符来实现的。
- 封装也称为数据(信息)隐藏。
- 封装提供了一种保持状态数据完整性的方法。应该定义私有数据字段,而不是定义公共字段。
- 封装良好的类应该向外界隐藏其数据以及其如何操作数据的细节。
- 使用此功能,类作者可以更改方法的实现,而不会破坏任何使用它的现有代码。
55. C# 中 Yield 关键字有什么用途?
- Yield 关键字可帮助您对 .NET 集合进行自定义状态迭代
- 在两种情况下,“yield”关键字很有用,
- 它有助于提供自定义迭代而无需创建临时集合。
- 它有助于进行全状态迭代。
56. 如何在 C# 中一次捕获多个异常?
您可以使用 C# 中的条件语句捕获多个异常。
57. C#中IDisposable接口有什么用途?
- IDisposable 接口的主要用途是清理非托管资源。
- “非托管”是指数据库连接、套接字等。
58. C#.net 中的属性是什么?
- 属性是提供灵活机制来读取、写入或计算私有字段值的成员。
- 换句话说,通过属性,我们可以访问私有字段。
- 属性是具有一个参数或不具有参数的返回类型函数/方法。
- 这些始终是公共数据成员。
- 它使用方法来访问和分配值给称为访问器的私有字段。
59. 什么是访问器?
属性的 Get 和 Set 部分或块称为访问器。
60. 什么是部分类(Partial)?
- 部分类仅用于将一个类的定义拆分为同一个源代码文件或多个源文件中的两个或多个类。
- 您可以在多个文件中创建类定义,但它将在运行时以及您创建此类的实例时被编译为一个类。因此,您可以使用同一个对象访问所有源文件中的所有方法。
- 可以在同一个命名空间中创建部分类,但不允许在不同的命名空间中创建部分类。
- 您可以将“partial”关键字与您想要绑定在一起的所有类名以及同一命名空间中的相同类名一起使用。
61. 什么是密封类?
- 密封类用于限制面向对象编程的继承特性。
- 一旦将某个类定义为密封类,那么该类就不能被继承。
- 出于安全原因限制继承的类被声明为密封类。
- 密封类是层次结构中的最后一个类。
- 密封类可以是派生类,但不能是基类。
- 密封类不能同时是抽象类。因为抽象类必须提供功能,而这里您限制它只能继承。
- 如果你曾经注意到,结构和枚举是密封的。
62.什么是密封方法和属性?
- 密封方法用于定义虚方法的覆盖级别。
- sealed 关键字总是与 override 关键字一起使用。
63. 在 C# 中如何从派生类调用基类构造函数?
使用基本关键字进行此类初始化。
64. 什么是基本关键词?
- base 关键字用于从派生类中访问基类的成员。
- 调用基类上已被另一个方法重写的方法。
- 指定在创建派生类的实例时应调用哪个基类构造函数。
- 在静态方法中使用 base 关键字是错误的。
65.三层架构有什么好处?
- 可重用性:
您可以使用不同的用户界面(如 ASP.NET、窗口等)重复使用中间层。
您还可以在不同的项目中重复使用 DAL。 - 可维护性:
当您由于模块化方法而在某一层中进行更改时,它不会对其他层产生连锁反应。
当您改变一层的逻辑时,您只需在另一层做较少的更改。
66. 设计模式和架构模式有什么区别?
- 设计模式
它们是解决技术问题的著名模式,并且已经被多次证明。
它们是用于创建可重用的面向对象软件的常见设计结构和实践。
设计模式示例有工厂模式、单例模式、外观模式、状态模式等。
它们可用于解决整个应用程序中较小的问题,并且比整体架构更容易注入、更改和添加。 - 架构模式
它们是解决软件应用程序架构问题的著名模式。
软件应用程序架构是定义满足所有技术和操作要求的结构化解决方案的过程。
应用程序的架构是代码的整体“组织”。
不同架构的示例可能是 MVC、MVVM、MVP、n 层(即 UI-BLL-DAL)等。
架构通常需要提前决定,并且一旦应用程序构建完成通常很难更改。
67. C# 中的构造函数链是什么?
构造函数链是一种构造函数调用同一类或基类中的另一个构造函数的方法。
68. C# 中的 this 和 base 有什么区别?
- this
这是指的是当前实例(而不是“当前类”)。
它只能在非静态方法/成员中使用。因为静态方法中没有当前实例。
在此调用方法将以与在包含相同实例的变量上调用方法相同的方式调用该方法。 - base
是一个允许继承方法调用的关键字,即从基类型调用指定的方法。
它只能在非静态方法中使用。
它通常用于虚拟方法重写,但实际上可用于调用基类型中的任何方法。
它与正常的方法调用非常不同,因为它绕过了正常的虚拟方法调度。
即使它是虚拟的,它也直接调用基方法。