C# 继承

在 C# 中,继承允许我们从现有类创建新类。它是面向对象编程 (OOP) 的一个关键特性。

创建新类的类称为基类(父类或超类)。而新类称为派生类(子类或次类)。

派生类继承基类的字段和方法。这有助于 C# 中的代码重用。


如何在 C# 中执行继承?

在 C# 中,我们使用 : 符号来执行继承。例如,

class Animal {  
  // fields and methods
} 

// Dog inherits from Animal
class Dog : Animal {
  // fields and methods of Animal 
  // fields and methods of Dog 
}

在这里,我们从基类 Animal 派生了 Dog 类。 Dog 类现在可以访问 Animal 类的字段和方法。

C# Inheritance
C# 继承


示例:C# 继承

using System;

namespace Inheritance {

  // base class
  class Animal { 

    public string name;

    public void display() {
      Console.WriteLine("I am an animal");
    }
    
  } 
  
// derived class of Animal class Dog : Animal {
public void getName() { Console.WriteLine("My name is " + name); } } class Program { static void Main(string[] args) { // object of derived class Dog labrador = new Dog();
// access field and method of base class labrador.name = "Rohu"; labrador.display();
// access method from own class labrador.getName(); Console.ReadLine(); } } }

输出

I am an animal
My name is Rohu

在上面的示例中,我们从超类 Animal 派生了子类 Dog。注意以下语句:

labrador.name = "Rohu";

labrador.getName();

在这里,我们使用 labrador(Dog 的对象)来访问 Animal 类的 namedisplay()。这是可能的,因为派生类继承了基类的所有字段和方法。

此外,我们在 Dog 类的类方法中访问了 name 字段。


is-a 关系

在 C# 中,继承是一种“is-a”关系。只有当两个类之间存在“is-a”关系时,我们才使用继承。例如,

  • 动物
  • **苹果**是**水果**
  • **汽车**是**交通工具**

我们可以从 Animal 类派生 Dog。同样,从 Fruit 类派生 Apple,从 Vehicle 类派生 Car


C# 继承中的 protected 成员

当我们声明一个字段或方法为 protected 时,它只能从同一类及其派生类中访问。

示例:继承中的 protected 成员

using System;

namespace Inheritance {

  // base class
  class Animal { 
protected void eat() { Console.WriteLine("I can eat"); }
} // derived class of Animal class Dog : Animal { static void Main(string[] args) { Dog labrador = new Dog();
// access protected method from base class labrador.eat();
Console.ReadLine(); } } }

输出

I can eat

在上面的示例中,我们创建了一个名为 Animal 的类。该类包含一个受保护的方法 eat()

我们从 Animal 类派生了 Dog 类。注意以下语句:

labrador.eat();

由于 protected 方法可以从派生类访问,因此我们可以从 Dog 类访问 eat() 方法。


继承的类型

继承有以下几种类型:

1. 单一继承

在单一继承中,一个派生类继承自一个基类。

C# Single Inheritance
C# 单一继承

2. 多层继承

在多层继承中,一个派生类继承自一个基类,然后该派生类又成为另一个类的基类。

C# Multilevel Inheritance
C# 多层继承

3. 层次继承

在层次继承中,多个派生类继承自一个基类。

C# Hierarchical Inheritance
C# 层次继承

4. 多重继承

在多重继承中,一个派生类继承自多个基类。C# 不支持多重继承。 但是,我们可以通过接口实现多重继承。

Multiple Inheritance
多重继承

5. 混合继承

混合继承是两种或多种继承类型的组合。多层继承和层次继承的组合是混合继承的一个例子。

C# Hybrid Inheritance
C# 混合继承

C# 继承中的方法重写

如果基类和派生类中都存在相同的方法,则派生类中的方法会覆盖基类中的方法。这在 C# 中称为方法重写。例如,

using System;

namespace Inheritance {

  // base class
  class Animal { 
public virtual void eat() { Console.WriteLine("I eat food"); }
} // derived class of Animal class Dog : Animal { // overriding method from Animal
public override void eat() { Console.WriteLine("I eat Dog food"); }
} class Program { static void Main(string[] args) { // object of derived class Dog labrador = new Dog(); // accesses overridden method labrador.eat(); } } }

输出

I eat Dog food

在上面的示例中,eat() 方法同时存在于基类和派生类中。

当我们使用 Dog 对象 labrador 调用 eat() 时,

labrador.eat();

会调用 Dog 中的方法。这是因为 Dog 中的方法会重写 Animal 中的相同方法。

请注意,我们对基类和派生类的方法使用了 virtualoverride。在这里:

  • virtual - 允许派生类重写该方法
  • override - 指示该方法正在重写基类中的方法

C# 继承中的 base 关键字

在前一个示例中,我们看到派生类中的方法会重写基类中的方法。

但是,如果我们想调用基类中的方法怎么办?

在这种情况下,我们使用 base 关键字从派生类调用基类中的方法。

示例:C# 继承中的 base 关键字

using System;

namespace Inheritance {

  // base class
  class Animal { 
    public virtual void eat() {

      Console.WriteLine("Animals eat food.");
    }
  } 
  
  // derived class of Animal 
  class Dog : Animal {

    // overriding method from Animal
    public override void eat() {
      
// call method from Animal class base.eat();
Console.WriteLine("Dogs eat Dog food."); } } class Program { static void Main(string[] args) { Dog labrador = new Dog(); labrador.eat(); } } }

输出

Animals eat food.
Dogs eat Dog food.

在上面的示例中,eat() 方法同时存在于基类 Animal 和派生类 Dog 中。注意以下语句:

base.eat();

在这里,我们使用 base 关键字从 Dog 类访问 Animal 类的方法。


C# 继承的重要性

为了理解继承的重要性,让我们考虑一个场景。

假设我们正在处理汽车和自行车等不同类型的车辆,并且需要根据给定的初始速度、加速度和时间输入来计算这些车辆的速度。

1. 由于计算速度的公式对所有车辆都是通用的,因此我们可以创建一个 Vehicle 类,其中包含一个 calculateSpeed() 方法来计算速度。

class Vehicle
{
    public void calculateSpeed()
    {
        // Code to compute speed
    }
}

2. 然后,我们从 Vehicle 类派生两个类:CarBicycle。这些类继承了 VehiclecalculateSpeed() 方法,但会包含存储初始速度、加速度和时间的属性,因为这些属性因车辆而异。

class Car : Vehicle
{
    public int initialSpeed = 0;
    public double acceleration = 9.8;
    public double time = 10;
}

我们将 initialSpeedaccelerationtime 的值传递给 calculateSpeed() 以计算最终速度。

这就是继承如何使我们的代码可重用且更直观。

示例:继承的重要性

using System;

namespace Inheritance
{

    // Base class for all vehicles
    class Vehicle
    {
        // Method to calculate the speed after a given time
        public void calculateSpeed(int initialSpeed, double acceleration, double time)
        {
            double finalSpeed = initialSpeed + acceleration * time;
            Console.WriteLine("Final speed after " + time + " seconds is " + finalSpeed + " m/s.");
        }

    }

    // Derived class for Cars
    class Car : Vehicle
    {
        // Initial speed in m/s
        public int initialSpeed = 0;
        // Acceleration in m/s²
        public double acceleration = 9.8;
        // Time in seconds  
        public double time = 10;

        public void displayCarDetails()
        {
            Console.WriteLine("Car is moving at an initial speed of " + initialSpeed + " m/s.");
        }
    }

    // Derived class for Bicycles
    class Bicycle : Vehicle
    {
        // Initial speed in m/s
        public int initialSpeed = 5;
        // Acceleration in m/s²
        public double acceleration = 0.5;
        // Time in seconds  
        public double time = 10;

        public void displayBicycleDetails()
        {
            Console.WriteLine("Bicycle is moving at an initial speed of " + initialSpeed + " m/s.");
        }
    }

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

            Car myCar = new Car();
            myCar.displayCarDetails();
            myCar.calculateSpeed(myCar.initialSpeed, myCar.acceleration, myCar.time);

            Bicycle myBicycle = new Bicycle();
            myBicycle.displayBicycleDetails();
            myBicycle.calculateSpeed(myBicycle.initialSpeed, myBicycle.acceleration, myBicycle.time);
        }
    }
}

输出

Car is moving at an initial speed of 0 m/s.
Final speed after 10 seconds is 98 m/s.
Bicycle is moving at an initial speed of 5 m/s.
Final speed after 10 seconds is 10 m/s.

在上面的示例中,我们创建了一个 Vehicle 类,其中包含一个根据初始速度和加速度在给定时间内计算车辆速度的方法。

在这里,CarBicycle 都继承自 Vehicle 类。

速度计算公式对所有车辆都是通用的,因此我们重用了基类的 calculateSpeed() 方法。

由于显示车辆详细信息的具体内容可能因车辆类型(如汽车或自行车)而异,因此我们在派生类中创建了单独的方法来显示这些详细信息。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战