跳转至

方法与面向对象复习#

对应笔记:方法(函数)类与对象(预习)类与对象基础继承虚方法抽象类接口静态成员结构体与枚举 建议用时:70 分钟。


一、选择题#

1. refout 参数的区别是?

  • A. 没有区别
  • B. ref 传入前必须赋值,out 传入前不用赋值
  • C. out 传入前必须赋值,ref 不用
  • D. ref 只能用于值类型
答案

B。ref:传入前必须赋值(双向);out:传入前不用赋值,但方法内必须赋值(单向输出)。两者都能传出多个值,弥补 return 只能返回一个的限制。

2. 方法重载(Overload)的正确条件是?

  • A. 方法名相同、返回值不同
  • B. 方法名相同、参数列表不同(个数/类型)
  • C. 方法名不同、参数相同
  • D. 只要返回值不同就算重载
答案

B。重载要求:方法名相同 + 参数列表不同(参数个数或类型不同)。仅返回值不同不算重载,会编译错误。

3. 下列哪个修饰符表示"只有当前类内部可访问"?

  • A. public
  • B. internal
  • C. private
  • D. protected
答案

C. private。public 全部可访问;internal 当前项目;protected 当前类及子类;protected internal 当前项目 + 其他项目子类。

4. 子类继承父类后,下列说法正确的是?

  • A. 可以继承父类所有 private 成员
  • B. 可以继承父类 public / protected 成员
  • C. 一个类可以继承多个父类
  • D. 子类不能增加新成员
答案

B。C# 单继承——一个类只能继承一个父类;private 成员不能被子类访问;子类可以扩展新成员。

5. 抽象类(abstract)与接口(interface)的区别,错误的是?

  • A. 抽象类可以有字段和普通方法
  • B. 接口只能有方法签名和属性(无实现)
  • C. 一个类可以实现多个接口
  • D. 抽象类可以实例化(new)
答案

D。抽象类不能实例化,只能被继承。抽象类可有实现和字段;接口纯规范,可实现多个。

6. static 静态成员的特点,错误的是?

  • A. 通过 类名.成员 访问
  • B. 所有对象共享一份
  • C. 静态方法可以访问实例成员
  • D. 生命周期从类加载到程序结束
答案

C。静态方法不能直接访问非静态(实例)成员,因为没有 this 引用;静态成员属于类,所有对象共享。

7. 虚方法(virtual)与抽象方法(abstract)的区别?

  • A. 没有区别
  • B. 虚方法有默认实现,抽象方法没有实现
  • C. 抽象方法有默认实现
  • D. 虚方法只能在抽象类中
答案

B。虚方法有默认实现、子类可选重写;抽象方法无实现、子类必须 override,且只能在抽象类中声明。


二、填空题#

1. 面向对象三大特性:==_== ==== ==_== ====、==_== ==== ==_== ====、==_== ==== ==_== ====。

答案

封装、继承、多态。

2. 类的默认访问修饰符是 ==_== ==== ==_== ====,类成员的默认修饰符是 ==_== ==== ==_== ====。

答案

internal(当前项目);private(类内)。

3. 子类构造函数执行顺序:先执行 ==_== ==== ==_== ==== 的构造函数,再执行 ==_== ==== ==_== ==== 的构造函数。

答案

父类(基类);子类(派生类)。多层继承时从最顶层基类逐层向下。

4. 构造函数链式调用使用 ==_== ==== ==_== ==== 关键字调用本类其他构造函数,用 ==_== ==== ==_== ==== 关键字调用父类构造函数。

答案

this(...)base(...)。两者不能同时使用。

5. const 是 ==_== ==== ==_== ==== 时确定值,readonly 是 ==_== ==== ==_== ==== 时确定值。

答案

编译时(声明时必须初始化);运行时(声明时或构造函数中初始化)。

6. 结构体是 ==_== ==== ==_== ==== 类型(值/引用),类是 ==_== ==== ==_== ==== 类型。

答案

值类型(struct);引用类型(class)。


三、代码分析题#

1. 阅读代码,写出输出结果。

class Animal
{
    public virtual void Speak() { Console.WriteLine("动物叫"); }
}
class Dog : Animal
{
    public override void Speak() { Console.WriteLine("汪汪汪"); }
}
Animal a = new Dog();
a.Speak();
答案

汪汪汪。父类引用指向子类对象时,调用虚方法会动态分派到子类重写版本(运行时多态)。

2. 阅读代码,写出执行顺序。

class A { public A() { Console.WriteLine("A"); } }
class B : A { public B() { Console.WriteLine("B"); } }
new B();
答案

先输出 A,再输出 B。创建子类实例时,先调用父类构造函数,再调用子类构造函数。

3. 下列代码哪里有问题?

public void Eat() { }
public int Eat() { return 1; }
答案

编译错误:仅返回值不同不算重载。两个方法名相同、参数列表相同,仅返回值不同,编译器无法区分。

4. 阅读代码,输出结果。

class Test
{
    static int num = 0;
    public void Add() { num++; }
    public void Show() { Console.WriteLine(num); }
}
Test t1 = new Test();
Test t2 = new Test();
t1.Add(); t1.Add();
t2.Add();
t1.Show();
答案

3num 是静态成员,所有对象共享同一份,t1 加 2 次、t2 加 1 次,共 3。


四、编程题#

1. 用继承实现:基类 Shape(抽象方法 Area),子类 CircleRectangle 实现面积计算。

答案
abstract class Shape
{
    public abstract double Area();
}
class Circle : Shape
{
    public double R { get; set; }
    public override double Area() { return Math.PI * R * R; }
}
class Rectangle : Shape
{
    public double W { get; set; }
    public double H { get; set; }
    public override double Area() { return W * H; }
}

2. 用方法重载实现:计算正方形、长方形、梯形的面积。

答案
public static double Area(int side) { return side * side; }        // 正方形
public static double Area(int w, int h) { return w * h; }          // 长方形
public static double Area(int top, int bottom, int h)              // 梯形
{
    return (top + bottom) * h / 2.0;
}

3. 定义一个 Person 类(姓名、年龄、性别),用属性校验年龄必须在 0~150 之间。

答案
class Person
{
    private int age;
    public string Name { get; set; }
    public string Sex { get; set; }
    public int Age
    {
        get { return age; }
        set { if (value >= 0 && value <= 150) age = value; }
    }
}

4. 用 ref/out 实现:一个方法同时返回两个数的和与差。

答案
public static void Calc(int a, int b, out int sum, out int diff)
{
    sum = a + b;
    diff = a - b;
}
// 调用
Calc(10, 3, out int s, out int d);  // s=13, d=7

5. 用接口实现:IUsb 接口(Read 方法),MouseKeyboard 类实现它。

答案
interface IUsb { void Read(); }
class Mouse : IUsb
{
    public void Read() { Console.WriteLine("鼠标读取"); }
}
class Keyboard : IUsb
{
    public void Read() { Console.WriteLine("键盘读取"); }
}

知识卡片#

面向对象三大特性?

封装(属性/访问修饰符控制访问)、继承(代码复用,单继承)、多态(虚方法 override 动态分派)。

refout 的区别?

ref 传入前必须赋值、双向;out 传入前不用赋值、方法内必须赋值、单向输出。都能一次传出多个值。

方法重载的条件?

同名 + 参数列表不同(个数/类型/顺序);仅返回值不同不算重载。

访问修饰符权限从大到小?

public > protected internal > internal > protected > private。

继承中构造函数的执行顺序?

先父类后子类;多层继承从顶层基类逐层向下。可用 base() 指定调用父类哪个构造函数。

抽象类 vs 接口?

抽象类可有实现/字段、单继承、子类 override;接口纯规范、多实现、成员无实现。

虚方法 vs 抽象方法?

虚方法有默认实现、可选重写;抽象方法无实现、必须重写、只能在抽象类中。

静态成员的特点?

属于类、所有对象共享、通过类名访问、静态方法不能访问实例成员。

struct 与 class 的区别?

struct 值类型(栈)、不能继承、无参构造受限;class 引用类型(堆)、可继承。

const 与 readonly?

const 编译时常量(声明时初始化、隐式 static);readonly 运行时常量(声明或构造函数中初始化、实例级)。


相关笔记#