.NET/C#⾯试题汇总系列:⾯向对象
1.什么是构造函数?
用于初始化新创建对象的特殊方法。它们没有返回类型,并且其名称与类名相同
构造函数(Constructor)是一种特殊的方法,它用于在创建对象时初始化该对象。
构造函数没有返回类型(连void
也没有),并且其名称必须与类名完全相同。
构造函数的主要目的是确保每次创建对象时,对象都能被正确地初始化。
2.class和struct的区别?
相同点
都可以实现接⼝
不同点
- 1.class是引⽤类型,struct是值类型
- 2.class允许继承、被继承,struct不允许,只能继承接⼝
- 3.class可以初始化变量,struct不可以
- 4.class可以有⽆参的构造函数,struct不可以,必须是有参的构造函数,⽽且在有参的构造函数必须初始 化所有成员
使⽤场景
- 1.Class⽐较适合⼤的和复杂的数据,表现抽象和多级别的对象层次时。
- 2.Struct适⽤于作为经常使⽤的⼀些数据组合成的新类型,表示诸如点、矩形等主要⽤来存储数据的轻量 级对象时,偏简单值。
- 3.Struct有性能优势,Class有⾯向对象的扩展优势。
3.简述⼀下⾯向对象的三⼤特性?
封装:封装是指将数据和操作数据的方法组合在一起,形成一个类。封装的目的是隐藏内部实现细节,只暴露必要的接口给外部使用。这样可以保护数据的安全性,并提高代码的可维护性和可重用性。
继承:继承是一种创建新类的方式,新类继承了现有类的属性和方法。通过继承,子类可以重用父类的代码,减少重复代码,并且可以在子类中添加新的属性和方法或者覆盖父类的方法。继承提供了一种层次结构,使得代码更加模块化和易于扩展。
多态:多态是指不同对象对同一消息的不同响应能力。在面向对象编程中,多态允许一个接口或方法在不同的对象上具有不同的实现。这意味着可以使用相同的接口来处理不同类型的对象,而不需要知道对象的具体类型。多态提高了代码的灵活性和可扩展性,使得程序更容易适应变化。
4.构造函数是否能被重写?
构造函数在C#中不能被重写,但可以被重载来提供不同的初始化方式
在C#中,构造函数(Constructor)是一种特殊类型的方法,用于在创建对象时初始化对象。
它不能被重写(Override),但可以被重载(Overload)。
这是因为构造函数没有返回类型(甚至连
void
都没有),并且它们的名称必须与类名相同,这些特性使得它们不能按照多态的方式进行重写
5.抽象类和接⼝有什么区别?
相同点:
都不能直接实例化
不同点:
1.抽象类⽤abstract修饰、接⼝⽤interface修饰
2.抽象类中的⽅法可以实现,也可以不实现,有抽象⽅法的类⼀定要⽤abstract修饰,接⼝中的⽅法不允 许实现
3.抽象类只能单继承,接⼝⽀持多实现
4.抽象类有构造⽅法,接⼝不能有构造⽅法
5.接⼝只负责功能的定义,通过接⼝来规范类的,(有哪些功能),⽽抽象类即负责功能的定义有可以实 现功能(实现了哪些功能)
6..类的执⾏顺序?
静态成员(包括静态字段和静态构造函数):当类被首次引用时(如创建类的实例、访问类的静态成员等),静态构造函数会执行一次,静态字段会按它们在类中出现的顺序进行初始化(如果它们在声明时就被初始化了)。
实例成员(包括字段、属性、实例构造函数等):当创建类的实例时,首先会执行字段初始化块(如果存在),然后是实例构造函数,构造函数中可能包含对字段的进一步初始化。
方法:类的方法(无论是实例方法还是静态方法)的执行顺序完全取决于它们在代码中的调用顺序。
7.接⼝是否可继承接⼝?抽象类是否可实现(implements)接⼝?抽象类是否可继承实现类 (concrete class)?
接⼝可以继承接⼝,抽象类可以实现接⼝,抽象类可以继承实现类,但前提是实现类必须有明确的构造函 数。
- 接口可以继承其他接口,这意味着一个接口可以继承多个接口的成员。这种继承允许创建更复杂的接口,其中包含多个接口的特性。
- 抽象类可以实现(implements)接口,这意味着抽象类必须提供接口中声明的所有抽象方法的具体实现。抽象类也可以继承其他抽象类,并且可以包含自己的抽象方法和非抽象方法。
- 抽象类不能直接继承实现类(concrete class),因为实现类是具体的,它提供了所有成员的具体实现。抽象类的目的是定义一种契约,让派生类去实现这些契约,而不是提供具体实现。因此,抽象类只能被继承,而不能被实例化。
8.继承最⼤的好处?
对⽗类成员进⾏重⽤,增加代码的可读性、灵活性。
9.请说说引⽤和对象?
- 对象和引⽤时分不开的,对象⽣成⼀个地址,放在堆⾥⾯,引⽤则指向这个地址,放在栈⾥⾯。
- 对象是具有状态和行为的实体,而引用是指向这些对象的指针或标识符
引用(Reference)和对象(Object)是面向对象编程中两个重要的概念。
对象:对象是面向对象编程的基本构建块,它表示现实世界中的一个实体或概念。每个对象都有一组属性(也称为成员变量或字段)和方法(也称为成员函数或操作)。对象的属性描述了对象的状态,而方法定义了对象的行为。在C#中,对象是通过类来创建的实例。
引用:引用是一个指向对象的指针或标识符。当我们创建一个对象时,实际上是在内存中分配空间来存储该对象的数据,并返回一个指向该内存位置的引用。我们可以使用这个引用来访问和操作对象的属性和方法。引用可以是变量、参数传递、数组元素等。
10.什么是匿名类,有什么好处?
匿名类(Anonymous Class)是指在C#中使用没有显式命名的类。匿名类通常用于创建临时的对象,这些对象只在某个特定的上下文中使用,并且不需要在其他地方引用。
不⽤定义、没有名字的类,使⽤⼀次便可丢弃。好处是简单、随意、临时的。
11.重写和重载的区别?
- 重写(Override):重写是指子类重新定义父类中已有的方法或属性的行为。
- 重载(Overload):重载是指在同一个类中定义多个同名但参数列表不同的方法。
- 重写⽅法:关键字⽤override修饰,派⽣类重写基类的⽅法,⽅法命名、返回类型,参数必须相同
- 重载⽅法:⽅法名必须相同,参数列表必须不相同,返回类型可以不相同。
12.C#中有没有静态构造函数,如果有是做什么⽤的?
特点: 静态构造函数既没有访问修饰符,也没有参数。在创建第⼀个实例或引⽤任何静态成员之前,将⾃ 动调⽤静态构造函数来初始化类。⽆法直接调⽤静态构造函数。在程序中,⽤户⽆法控制何时执⾏静态构 造函数。 ⽤途 : 当类使⽤⽇志⽂件时,将使⽤这种构造函数向⽇志⽂件中写⼊项。
13.怎样理解静态变量?静态成员和⾮静态成员的区别?
- 静态变量属于类,⽽不属于对象;
- 并对所有对象所享;
- 静态成员在加类的时候就被加载。
14.属性能在接⼝中声明吗?
可以,不能有访问修饰符,不能初始化赋值。
///IProduct接口声明了三个成员:一个无参数无返回值的方法PrintInfo,
///一个有参数有返回值的方法CalculatePrice,以及两个属性Name(只读)和
///Stock(可读可写)。然后,Product类实现了这个接口,并提供了所有接口
///成员的具体实现。
public interface IProduct
{
// 1. 无参数、无返回值的方法
void PrintInfo();
// 2. 有参数、有返回值的方法
double CalculatePrice(int quantity);
// 3. 声明属性
// 声明只读属性
string Name { get; }
// 声明读写属性
int Stock { get; set; }
}
// 实现接口的类
public class Product : IProduct
{
public string Name { get; private set; } // 私有设置器,外部不能修改Name
public int Stock { get; set; } // 外部可以读写Stock
public Product(string name, int stock)
{
Name = name;
Stock = stock;
}
public void PrintInfo()
{
Console.WriteLine($"Product Name: {Name}, Stock: {Stock}");
}
public double CalculatePrice(int quantity)
{
// 假设单价为10
return 10 * quantity;
}
}
15.在项⽬中为什么使⽤接⼝?接⼝的好处是什么?什么是⾯向接⼝开发?
解耦:接口提供了一种抽象的方式来定义对象的行为,使得实现类可以独立于接口的定义进行开发。这意味着如果需要更改接口的实现方式或替换具体的实现类,只需要修改实现类而不需要修改依赖于接口的其他代码。
提高可扩展性:接口允许多个不同的实现类来满足同一功能的需求。通过定义一个接口,我们可以为不同的场景提供不同的实现,从而增加系统的灵活性和可扩展性。
支持多态:接口允许我们以统一的方式处理不同类型的对象,只要它们实现了相同的接口。这使得我们可以编写通用的代码,而无需关心具体的对象类型。
便于测试:接口提供了一种隔离实现细节的方法,使得我们可以针对接口进行单元测试,而不必关心具体的实现细节。这有助于提高代码的质量和可靠性。
促进代码重用:接口可以作为公共契约,被多个不同的类所实现和使用。这样可以减少重复代码,并提高代码的可维护性和可读性。
16.什么时候⽤重载?什么时候⽤重写?
当⼀个类需要⽤不同的实现来做同⼀件事情,此时应该⽤重写,⽽重载是⽤不同的输⼊做同⼀件事情。
- 使用重载的场景:当你需要在同一个类中实现多个功能相似但参数不同的方法时,可以使用重载。例如,一个计算器类可以有多个加法方法,分别接受整数、浮点数、字符串等不同类型的参数。
- 使用重写的场景:当你需要在子类中扩展或修改父类的行为时,可以使用重写。例如,假设有一个动物类和一个狗类,狗类继承了动物类并重写了动物类的叫声方法,以提供狗特有的叫声。
17.静态⽅法可以访问⾮静态变量吗?如果不可以为什么?
静态方法无法直接访问非静态变量,因为它们不共享相同的生命周期和存储位置。如果需要在静态方法中使用非静态变量,可以通过创建类的实例来访问这些变量,或者将非静态变量改为静态变量。
18.在.Net中所有可序列化的类都被标记为____?
[serializable]
19.C#中 property 与 attribute的区别,他们各有什么⽤处,这种机制的好处在哪⾥?
⼀个是属性,⽤于存取类的字段,
⼀个是特性,⽤来标识类,⽅法等的附加性质
20.能⽤foreach遍历访问的对象需要实现 接⼝或声明⽅法的类型
答:IEnumerable 、 GetEnumerator。