C# 继承


C# 继承是一种面向对象的编程技术,使得子类可以继承父类的属性和方法,并且可以通过覆盖或增加方法来扩展父类的行为。本篇 Markdown 技术文档将详细介绍 C# 继承的基础概念、使用方法、继承的类型、使用注意事项等方面。

基础概念

类和对象

类是一种模板或蓝图,描述了一种对象的属性和行为。在 C# 中通过 class 关键字创建类。对象是类的一个实例,表示具体的事物或概念。在 C# 中可以使用 new 关键字创建对象。

继承

继承是一种机制,子类可以继承父类的所有属性和方法,并且可以通过覆盖或增加方法来扩展父类的行为。在 C# 中使用冒号 : 符号表示继承关系。例如,定义一个子类 Employee 继承父类 Person 可以这样写:

class Employee : Person
{
    // 子类的代码
}

使用方法

继承父类的成员

子类可以直接访问其父类中的公共成员,包括字段、属性、方法等。访问的方式可以通过 this 关键字来指定访问父类方法或属性。例如,下面的代码中,子类 Employee 继承了父类 Person 的属性和方法,并通过 this 关键字访问了父类的属性和方法。

class Person 
{
    public string Name { get; set; }
    public void PrintInfo() 
    {
        Console.WriteLine($"My name is {Name}");
    }
}

class Employee : Person 
{
    public void PrintEmployeeInfo() 
    {
        this.Name = "Tom";
        this.PrintInfo();
    }
}

覆盖父类的成员

子类可以覆盖父类的方法和属性。在子类中使用 override 关键字来标识,然后实现自己的方法或属性。例如,下面的代码中,子类 Employee 覆盖了父类 Person 的方法 PrintInfo()。

class Person 
{
    public virtual void PrintInfo() 
    {
        Console.WriteLine("This is a person.");
    }
}

class Employee : Person 
{
    public override void PrintInfo() 
    {
        Console.WriteLine("This is an employee.");
    }
}

增加成员

子类可以增加自己的属性和方法。例如,下面的代码中,子类 Employee 增加了自己的字段 Salary。

class Person 
{
    public string Name { get; set; }
    public void PrintInfo() 
    {
        Console.WriteLine($"My name is {Name}");
    }
}

class Employee : Person 
{
    public double Salary;
    public void PrintEmployeeInfo() 
    {
        Console.WriteLine($"My salary is {Salary}");
    }
}

继承的类型

单继承

C# 只支持单继承,即每个类只能继承一个父类,也就是说,一个子类只有一个直接父类。

class Person { }

class Employee : Person { }

class Manager : Employee { } // 错误:Manager 已经继承了Employee,不能再继承Person

多重继承

C# 不支持多重继承,即一个类不能同时继承多个父类。不过,C# 支持接口,可以在一个类中实现多个接口,达到多重继承的效果。

interface IA { }
interface IB { }

class C : IA, IB { } // C 继承了 IA 和 IB 接口

使用注意事项

访问修饰符

子类不能访问其父类的私有成员,只能访问公共和受保护的成员。私有成员可以通过公共或受保护的方法来访问。

class Person 
{
    private string Name { get; set; }
    public void SetName(string name) 
    {
        this.Name = name;
    }
}

class Employee : Person 
{
    public void PrintEmployeeInfo() 
    {
        this.SetName("Tom"); // 正确
        Console.WriteLine($"My name is {this.Name}"); // 错误:无法访问 private 成员
    }
}

父类构造函数

子类继承父类的构造函数,如果父类没有默认构造函数,则子类必须显式调用父类的构造函数。例如,下面的代码中,子类 Employee 必须显式调用父类 Person 的构造函数。

class Person 
{
    public string Name { get; set; }
    public Person(string name) 
    {
        this.Name = name;
    }
}

class Employee : Person 
{
    public double Salary;
    public Employee(string name, double salary) : base(name) 
    {
        this.Salary = salary;
    }
}

sealed 关键字

有时候,我们不希望子类进一步继承某个类,可以在类前加上 sealed 关键字来防止继承。例如,下面的代码中,Employee 类不能再被继承。

sealed class Person { }

class Employee : Person { } // 错误:不能继承 sealed 类

C# 继承是面向对象编程中重要的一个概念,实现了代码的复用和扩展,同时也需要注意继承的类型和使用注意事项。在实际编程中,应该学会合理地使用继承,避免出现类层次结构过于复杂的情况,提高代码的可维护性和可读性。