Logo
Section 1 / 7

继承

本课程详细讨论了继承,以及派生类和基类中的构造函数。

导入

继承

本课程详细讨论了继承,以及派生类和基类中的构造函数。

什么是继承

  • 提供了一种从现有类创建新类的方式。

  • 新类是现有类的特殊化版本。

  • 允许新类重用来自现有类的方法。

术语

  • 基类(或父类):被子类继承。
  • 派生类(或子类):从基类继承。

特性

一个派生类具有:

  • 派生类中定义的所有成员。
  • 基类中声明的所有成员。

一个派生类可以:

  • 使用在派生类中定义的所有 public 成员。
  • 使用在基类中定义的所有 public 成员。
  • 重写一个继承的成员。

一个派生类不能:

  • 继承构造函数和析构函数。
  • 改变继承成员的定义。

表示法

让我们看一下这两种类型的表示法。

1class Student { // 基类 2 // 内容 3} 4 5// 派生类通过使用 : 操作符从另一个类继承 6class UnderGrad : Student { 7 // 内容 8}

示例

考虑一个包含基类 Shape 和派生类 Square 的例子。

1using System; 2 3// 基类 4class Shape { 5 public Shape() { length = 0; } // 默认构造函数 6 public void setlength(int l) { length = l; } 7 protected int length; 8} 9 10// 派生类 11class Square : Shape { 12 public Square() { length = 0; } // 声明并初始化派生类构造函数 13 public int get_Area() { return (length * length); } 14} 15 16class Program 17{ 18 static void Main() 19 { 20 Square sq = new Square(); // 创建子类 Square 的对象 21 sq.setlength(5); // 将长度设置为 5 22 // 输出对象的面积 23 Console.WriteLine("正方形的总面积是: {0}", sq.get_Area()); 24 } 25}

如上例所示:

  • Shape 类是父类,而 Square 类是子类,它从 Shape 类派生而来。
  • 在我们的子类 Square 中,我们使用了父类的成员,例如:
    • protected 的 length 变量,在默认构造函数中被初始化为 零。
    • length 也在子类的 get_Area 函数中被用于计算正方形的面积。
  • 在 Main 方法中,setlength 函数作为父类的 public 成员函数,对子类对象 sq 是可访问的。
    • 使用点号操作符来访问 Main 中的 setlength。

构造函数

当创建 Square 类的实例时,如果没有显式调用父类中的其他构造函数,则会自动调用基类的默认构造函数(无参数)。

在本例中,首先调用 Shape 类的构造函数,然后调用 Square 类的构造函数。

在上述示例中,Square 类的构造函数调用了 Shape 类的默认构造函数。如果你愿意,也可以指定要调用哪个构造函数:可以使用 base 关键字调用父类中任何已定义的构造函数。

示例

为了更好地理解,请看下面的例子。

1using System; 2 3class Shape { 4 protected int length; 5 public Shape() { // 默认构造函数 6 Console.WriteLine("Shape 的默认构造函数"); 7 } 8 public Shape(int length) { // 带参数的构造函数 9 this.length = length; 10 Console.WriteLine("Shape 的带一个参数的构造函数"); 11 Console.WriteLine(this.length); 12 } 13} 14 15class Square : Shape { 16 public Square() : base() { // 使用 base 调用 Shape 类的默认构造函数 17 Console.WriteLine("Square 的默认构造函数"); 18 } 19 public Square(int length) : base(length) { // 使用 base 调用 Shape 类的带参数构造函数 20 Console.WriteLine("Square 的带一个参数的构造函数"); 21 Console.WriteLine(this.length); 22 } 23 public int get_Area() { return (length * length); } // 计算正方形面积的方法 24} 25 26class Program { 27 static void Main() { 28 Square sq1 = new Square(); // 创建子类 Square 的对象 29 Square sq2 = new Square(5); // 将长度设置为 5 30 Console.WriteLine("sq1 的面积是: {0}", sq1.get_Area()); 31 Console.WriteLine("sq2 的面积是: {0}", sq2.get_Area()); 32 } 33}

在上面的代码中:

  • 每个类都有两个构造函数。

  • 我们使用了 base 关键字,它是对父类的引用。

  • 在本例中,当我们创建 Square 类的实例时(第 28 行):

    • 运行时首先调用 Square(),即无参数的构造函数。但其主体并不会立即执行。
    • 在构造函数的括号之后,有一个 base() 调用,这意味着当我们调用 Square 的默认构造函数时,它会进一步调用父类的默认构造函数。
    • 父类构造函数执行完毕后返回,然后才执行 Square() 构造函数的主体。
  • 父类中非 private 的成员会被子类继承,这意味着 Square 类也拥有 length 字段。

    • 在这种情况下,第 29 行我们向构造函数传递了一个参数。
    • 它将该参数传递给父类的带参数构造函数,从而初始化 length 字段。

到目前为止有趣吗?在下一课中,我们将讨论多态性和虚方法。继续阅读以了解更多内容!

类

多态性与虚方法