# 📝 C# 面向对象程序设计 – 模拟考试试题

> 根据课堂复习内容编制 | 满分：100分 | 建议用时：60分钟

---

## 一、选择题（每题2分，共20分）

**1. 以下哪个访问修饰符的访问范围最小？**

A. `public`  
B. `private`  
C. `protected`  
D. `internal`

**2. 关于构造函数，以下说法正确的是？**

A. 构造函数可以有返回值  
B. 构造函数名可以与类名不同  
C. 构造函数方法名与类名相同，且没有返回类型声明  
D. 构造函数中必须使用 `return` 语句返回一个值

**3. 以下哪些情况属于方法重载？（多选）**

A. 方法名相同，参数个数不同  
B. 方法名相同，参数类型不同  
C. 方法名相同，参数列表相同，返回值类型不同  
D. 方法名相同，参数个数和类型都不同

**4. 静态方法（static method）可以被重写吗？**

A. 可以  
B. 不可以  
C. 取决于访问修饰符  
D. 只有 public 静态方法可以重写

**5. 在 C# 中，实现多态的前提是什么？**

A. 必须在同一个类中  
B. 必须基于继承关系  
C. 必须使用接口  
D. 必须使用抽象类

**6. 关于属性（Property）的描述，正确的是？**

A. 属性等同于字段，没有区别  
B. 属性通过 get 和 set 访问器控制读写权限  
C. 属性不能有 get 访问器  
D. 属性必须同时有 get 和 set

**7. 以下哪个命名空间包含了文件操作相关的类（如 FileStream）？**

A. `System.Data`  
B. `System.Text`  
C. `System.IO`  
D. `System.Collections`

**8. 以下代码的输出结果是什么？**

```csharp
int x = 5;
int y = 2;
double result = x / y;
Console.WriteLine(result);
```

A. 2.5  
B. 2  
C. 2.0  
D. 编译错误

**9. 关于析构函数，以下说法正确的是？**

A. 析构函数需要手动调用  
B. 析构函数在对象创建时自动执行  
C. 析构函数在对象脱离作用域时自动调用，用于释放资源  
D. 每个类必须显式编写析构函数

**10. 以下哪项是创建对象的正确语法？**

A. `Shape s1 = new Shape;`  
B. `Shape s1 = new Shape();`  
C. `Shape s1 = Shape();`  
D. `new Shape s1 = Shape();`

---

## 二、判断题（每题1分，共10分）

判断以下说法是否正确，正确打"✔"，错误打"✘"。

1. （ ）面向对象的三大基本特征是封装、继承和多态。
2. （ ）`public` 修饰的成员只能在本类中访问。
3. （ ）`protected` 修饰的成员可以在本类和子类中访问。
4. （ ）抽象方法必须有方法体。
5. （ ）静态方法可以被重写。
6. （ ）多态可以提高程序的扩展性。
7. （ ）`System.IO` 命名空间包含了文件操作类。
8. （ ）字段的默认值中，`int` 类型的默认值是 `null`。
9. （ ）`string` 类型的默认值是 `null`。
10. （ ）构造函数可以存在多个，参数列表不同，这称为构造函数重载。

---

## 三、填空题（每空2分，共20分）

1. 在 C# 中，访问类的成员使用 **____** 运算符。

2. 创建对象时需要使用 **____** 操作符。

3. 访问修饰符 `protected` 修饰的成员可以在 **____** 和 **____** 中访问。

4. `bool` 类型的字段默认值是 **____**。

5. 构造函数满足三个条件：① 方法名与类名相同；② **____**；③ 方法体中不能使用 `return` 语句返回值。

6. 析构函数是在构造函数前面加一个 **____** 符号。

7. 文件操作类 `FileStream` 位于 **____** 命名空间下。

8. 多态的两种实现方式是：① **虚方法 + override**；② **____ + 重写**。

9. 方法重载的区别在于参数的 **____** 不同或 **____** 不同。

10. 继承的语法是使用 **____** 符号。

---

## 四、程序改错题（每题5分，共10分）

### 题目1：找出以下程序中的错误并改正

```csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int[] numbers = new int[]{1, 2, 3, 4, 5};
        int sum;
        
        for(int i = 0; i <= numbers.Length; i++)
        {
            sum = sum + numbers[i];
        }
        
        double average = sum / numbers.Length;
        Console.WriteLine("平均值为：" + average);
    }
}
```

> 该程序有 **3处错误**，请找出并写出正确的代码。

| 错误位置 | 错误原因 | 改正后的代码 |
|---------|---------|-------------|
| 1 | | |
| 2 | | |
| 3 | | |

### 题目2：找出以下程序中的错误并改正

```csharp
using System;

class Shape
{
    public virtual double GetArea()
    {
        return 0;
    }
}

class Circle : Shape
{
    public double GetArea()    // 重写方法
    {
        return 3.14 * radius * radius;
    }
}
```

> 该程序有 **2处错误**，请找出并写出正确的代码。

| 错误位置 | 错误原因 | 改正后的代码 |
|---------|---------|-------------|
| 1 | | |
| 2 | | |

---

## 五、简答题（每题5分，共10分）

**1. 简述构造函数需要满足的三个条件。**

**2. 简述方法重载的定义以及它的判断规则。**

---

## 六、编程题（共30分）

### 题目：计算图形面积

请按照以下要求编写完整的 C# 控制台程序：

**要求：**

1. 创建一个抽象类（abstract class）`Shape`，包含：
   - 一个 `string` 类型的字段 `name`
   - 一个抽象方法 `GetArea()`，返回类型为 `double`

2. 创建一个类 `Circle`，继承自 `Shape`，包含：
   - 一个 `double` 类型的字段 `radius`
   - 构造函数：接收一个 `double` 参数 `r` 赋值给 `radius`，并设置 `name = "圆形"`
   - 重写 `GetArea()` 方法，计算圆的面积（公式：π × r²）

3. 创建一个类 `Rectangle`，继承自 `Shape`，包含：
   - 两个 `double` 类型的字段 `width` 和 `height`
   - 构造函数：接收两个 `double` 参数赋值给 `width` 和 `height`，并设置 `name = "矩形"`
   - 重写 `GetArea()` 方法，计算矩形的面积（公式：width × height）

4. 在 `Main()` 方法中：
   - 创建 `Circle` 对象（半径为 5.0）
   - 创建 `Rectangle` 对象（宽 4.0，高 6.0）
   - 分别输出它们的面积
   - 要求输出格式为：`[图形名称]的面积是：[面积值]`

> 提示：可以使用 `Math.PI` 表示圆周率。

**参考代码框架（请补全）：**

```csharp
using System;

// 抽象类 Shape


// Circle 类


// Rectangle 类


class Program
{
    static void Main(string[] args)
    {
        
    }
}
```

---

## 📖 参考答案

---

### 一、选择题答案

| 题号 | 答案 | 解析 |
|-----|------|------|
| 1 | **B** | `private` 仅本类可访问，范围最小 |
| 2 | **C** | 构造函数：方法名与类名相同，无返回类型，不能使用 return |
| 3 | **A、B、D** | 返回类型不同不能作为重载条件 |
| 4 | **B** | 静态方法不能被重写 |
| 5 | **B** | 多态必须基于继承关系 |
| 6 | **B** | 属性通过 get/set 控制读写 |
| 7 | **C** | `System.IO` 包含文件操作类 |
| 8 | **B** | int/int 结果为 int，5/2=2（整数除法） |
| 9 | **C** | 析构函数自动调用，用于释放资源 |
| 10 | **B** | `类名 对象名 = new 构造函数();` |

### 二、判断题答案

| 题号 | 答案 |
|-----|------|
| 1 | ✔ |
| 2 | ✘（public 所有类均可访问） |
| 3 | ✔ |
| 4 | ✘（抽象方法没有方法体） |
| 5 | ✘（静态方法不能被重写） |
| 6 | ✔ |
| 7 | ✔ |
| 8 | ✘（int 默认值为 0） |
| 9 | ✔ |
| 10 | ✔ |

### 三、填空题答案

| 题号 | 答案 |
|-----|------|
| 1 | `.`（点） |
| 2 | `new` |
| 3 | 本类、子类 |
| 4 | `false` |
| 5 | 方法名前没有返回值声明（连 void 都没有） |
| 6 | `~`（波浪线） |
| 7 | `System.IO` |
| 8 | 抽象类 + 抽象方法 |
| 9 | 个数、类型 |
| 10 | `:`（冒号） |

### 四、程序改错题答案

**题目1：**

| 错误位置 | 错误原因 | 改正后的代码 |
|---------|---------|-------------|
| `int sum;` | sum 未赋初值 | `int sum = 0;` |
| `i <= numbers.Length` | 数组越界 | `i < numbers.Length` |
| `sum / numbers.Length` | int/int 无法得到 double | `(double)sum / numbers.Length` |

**完整改正后的程序：**

```csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int[] numbers = new int[]{1, 2, 3, 4, 5};
        int sum = 0;                         // 修正1：初始化
        
        for(int i = 0; i < numbers.Length; i++)  // 修正2：< 而不是 <=
        {
            sum = sum + numbers[i];
        }
        
        double average = (double)sum / numbers.Length;  // 修正3：类型转换
        Console.WriteLine("平均值为：" + average);
    }
}
```

**题目2：**

| 错误位置 | 错误原因 | 改正后的代码 |
|---------|---------|-------------|
| `Circle` 类的 `GetArea()` | 重写虚方法缺少 `override` 关键字 | `public override double GetArea()` |
| `Circle` 类中未定义 `radius` 字段 | 使用了未声明的变量 | 需要添加 `private double radius;` 字段 |

**完整改正后的程序：**

```csharp
using System;

class Shape
{
    public virtual double GetArea()
    {
        return 0;
    }
}

class Circle : Shape
{
    private double radius;               // 添加字段
    
    public Circle(double r)              // 添加构造函数
    {
        radius = r;
    }
    
    public override double GetArea()     // 添加 override 关键字
    {
        return 3.14 * radius * radius;
    }
}
```

### 五、简答题参考答案

**1. 构造函数需要满足的三个条件：**

① 方法名**与类名相同**  
② 方法名前**没有返回值声明**（连 `void` 都不能写）  
③ 在方法体中**不能使用 `return` 语句返回一个值**

**2. 方法重载的定义及判断规则：**

- **定义**：在同一个类中，允许使用同一方法名定义多个方法。
- **判断规则**：方法名相同，但**参数的个数不同**或**参数的类型不同**。
- ❌ 仅返回值类型不同、参数列表相同，**不属于**方法重载。

### 六、编程题参考答案

```csharp
using System;

// 抽象类 Shape
abstract class Shape
{
    public string name;
    
    public abstract double GetArea();
}

// Circle 类
class Circle : Shape
{
    private double radius;
    
    public Circle(double r)
    {
        radius = r;
        name = "圆形";
    }
    
    public override double GetArea()
    {
        return Math.PI * radius * radius;
    }
}

// Rectangle 类
class Rectangle : Shape
{
    private double width;
    private double height;
    
    public Rectangle(double w, double h)
    {
        width = w;
        height = h;
        name = "矩形";
    }
    
    public override double GetArea()
    {
        return width * height;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Circle circle = new Circle(5.0);
        Rectangle rect = new Rectangle(4.0, 6.0);
        
        Console.WriteLine(circle.name + "的面积是：" + circle.GetArea());
        Console.WriteLine(rect.name + "的面积是：" + rect.GetArea());
    }
}
```

**预期输出：**
```
圆形的面积是：78.53981633974483
矩形的面积是：24
```

---

> 🎯 **做完后记得对照答案检查！考试加油！**
