程序设计基础
登录

知识介绍

继承(Is-A 关系):子类复用父类的成员,并扩展自己的功能。

// 父类(基类)
class Animal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public void Eat()
    {
        Console.WriteLine($"{Name}在吃东西");
    }
}

// 子类(派生类):继承 Animal
class Dog : Animal
{
    public string Breed { get; set; }  // 扩展字段

    public void Bark()                 // 扩展方法
    {
        Console.WriteLine($"{Name}({Breed})汪汪叫!");
    }
}

class Cat : Animal
{
    public void Meow()
    {
        Console.WriteLine($"{Name}喵喵叫");
    }
}

// 使用
Dog d = new Dog();
d.Name = "旺财";
d.Age = 2;
d.Breed = "柯基";
d.Eat();      // 旺财在吃东西  (继承自父类)
d.Bark();     // 旺财(柯基)汪汪叫!

子类构造与 base 关键字:

class Animal
{
    public string Name;
    public Animal(string name) { Name = name; }
}

class Dog : Animal
{
    public string Breed;
    // base(...) 调用父类有参构造
    public Dog(string name, string breed) : base(name)
    {
        Breed = breed;
    }
}

继承的特点:

  1. C# 是单继承:一个子类只能有一个父类
  2. 子类不能继承父类的构造方法,但能用 base 调用
  3. 子类可以用 new 隐藏父类同名方法(不推荐,用 override 更好,见2.4多态)
  4. 所有类默认继承自 object

例题

例题: 学校人员继承体系。

// 父类:学校人员
class SchoolMember
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }

    public SchoolMember(string name, int age, string gender)
    {
        Name = name; Age = age; Gender = gender;
    }

    public virtual void ShowInfo()  // virtual 标记虚方法,允许子类重写
    {
        Console.WriteLine($"姓名:{Name},年龄:{Age},性别:{Gender}");
    }
}

// 子类:学生
class Student : SchoolMember
{
    public string StudentId { get; set; }
    public string ClassName { get; set; }

    public Student(string name, int age, string gender, string sid, string className)
        : base(name, age, gender)   // 调用父类构造
    {
        StudentId = sid;
        ClassName = className;
    }

    public override void ShowInfo()  // override 重写
    {
        base.ShowInfo();   // 先执行父类版本
        Console.WriteLine($"学号:{StudentId},班级:{ClassName}");
    }

    public void Study()
    {
        Console.WriteLine($"{Name}正在{ClassName}学习");
    }
}

// 子类:老师
class Teacher : SchoolMember
{
    public string Subject { get; set; }
    public int YearsOfExp { get; set; }

    public Teacher(string name, int age, string gender, string subject, int yoe)
        : base(name, age, gender)
    {
        Subject = subject; YearsOfExp = yoe;
    }

    public override void ShowInfo()
    {
        base.ShowInfo();
        Console.WriteLine($"教{Subject},教龄{YearsOfExp}年");
    }

    public void Teach()
    {
        Console.WriteLine($"{Name}老师正在教授{Subject}");
    }
}

// 调用
Student stu = new Student("小明", 15, "男", "2024001", "高一3班");
stu.ShowInfo(); stu.Study();
Console.WriteLine("---");
Teacher tea = new Teacher("王老师", 35, "女", "数学", 10);
tea.ShowInfo(); tea.Teach();

练习题

  1. 定义一个 Shape(形状)基类,字段 color;派生 Square(正方形,多 side)、Rectangle(矩形,多 w,h),每个子类写 GetArea() 方法。

  2. 定义一个 Vehicle(交通工具)基类:brand、Run() 方法;派生 Car(多 doors)和 Bicycle(多 gear),都写一个 ShowInfo() 输出信息。

  3. 定义一个 Person 类(name、age、Introduce()),派生 Programmer:多 skills(技能数组)和 Code() 方法;派生 Designer:多 tool(设计工具)和 Draw() 方法。

  4. 在第3题基础上,使用 protected 字段,让子类可以直接访问 name 和 age,而不用通过 public 属性。