base 关键字的作用base 关键字用于在派生类中访问基类的成员(字段、方法、属性、构造函数等)。当派生类重写或隐藏了基类成员时,base 提供了一种方式来调用原始实现。
| 作用 | 说明 |
|---|---|
| 调用基类构造函数 | 在派生类构造函数中指定调用哪个基类构造函数 |
| 访问被重写的方法 | 在 override 方法中调用基类的原始实现 |
| 访问被隐藏的成员 | 当用 new 关键字隐藏基类成员时,用 base 访问原成员 |
csharp
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
// 基类构造函数
public Animal(string name)
{
Name = name;
Console.WriteLine($"Animal 构造函数执行,Name = {name}");
}
public Animal(string name, int age) : this(name) // 构造函数链
{
Age = age;
Console.WriteLine($"Animal 构造函数执行,Age = {age}");
}
}
public class Dog : Animal
{
public string Breed { get; set; }
// 使用 base 调用基类构造函数
public Dog(string name, string breed) : base(name) // 调用 Animal(string name)
{
Breed = breed;
Console.WriteLine($"Dog 构造函数执行,Breed = {breed}");
}
public Dog(string name, int age, string breed) : base(name, age) // 调用 Animal(string, int)
{
Breed = breed;
Console.WriteLine($"Dog 构造函数执行,Breed = {breed}");
}
}
// 使用示例
Dog dog1 = new Dog("旺财", "金毛");
// 输出:
// Animal 构造函数执行,Name = 旺财
// Dog 构造函数执行,Breed = 金毛
Dog dog2 = new Dog("来福", 3, "德国牧羊犬");
// 输出:
// Animal 构造函数执行,Name = 来福
// Animal 构造函数执行,Age = 3
// Dog 构造函数执行,Breed = 德国牧羊犬
csharp
public class Vehicle
{
public virtual void Start()
{
Console.WriteLine("车辆正在启动...");
}
public virtual void Stop()
{
Console.WriteLine("车辆已停止");
}
}
public class Car : Vehicle
{
public override void Start()
{
// 先执行基类的启动逻辑
base.Start();
Console.WriteLine("汽车发动机已点火,松手刹,挂挡");
}
public override void Stop()
{
Console.WriteLine("汽车踩刹车,拉手刹");
// 后执行基类的停止逻辑
base.Stop();
}
}
public class ElectricCar : Car
{
public override void Start()
{
base.Start(); // 调用 Car.Start(),而 Car.Start() 内部会调用 Vehicle.Start()
Console.WriteLine("电动汽车:电池供电,电机启动,静音行驶");
}
}
// 使用示例
Car myCar = new Car();
myCar.Start();
// 输出:
// 车辆正在启动...
// 汽车发动机已点火,松手刹,挂挡
myCar.Stop();
// 输出:
// 汽车踩刹车,拉手刹
// 车辆已停止
csharp
public class Parent
{
public string Name = "Parent";
public void ShowMessage()
{
Console.WriteLine("Parent 的 ShowMessage 方法");
}
public virtual void Display()
{
Console.WriteLine("Parent 的 Display 方法");
}
}
public class Child : Parent
{
// 使用 new 关键字隐藏基类的 Name 字段
public new string Name = "Child";
// 使用 new 关键字隐藏基类的方法
public new void ShowMessage()
{
Console.WriteLine("Child 的 ShowMessage 方法");
}
public override void Display()
{
// 调用基类的 Display(因为是 override,不是隐藏)
base.Display();
Console.WriteLine("Child 添加额外行为");
}
public void ShowAllNames()
{
Console.WriteLine($"Child.Name = {this.Name}"); // 输出 Child
Console.WriteLine($"base.Name = {base.Name}"); // 输出 Parent
}
public void CallBothMessages()
{
this.ShowMessage(); // 调用 Child 的版本
base.ShowMessage(); // 调用 Parent 的版本
}
}
// 使用示例
Child child = new Child();
child.ShowAllNames();
// 输出:
// Child.Name = Child
// base.Name = Parent
child.CallBothMessages();
// 输出:
// Child 的 ShowMessage 方法
// Parent 的 ShowMessage 方法
child.Display();
// 输出:
// Parent 的 Display 方法
// Child 添加额外行为
base 与 this 的对比| 对比维度 | base | this |
|---|---|---|
| 指向 | 基类的成员 | 当前类的实例 |
| 构造函数调用 | 调用基类构造函数 | 调用当前类的其他构造函数 |
| 访问被重写成员 | 可以访问基类版本 | 访问当前类版本 |
| 在静态方法中使用 | ❌ 不可以 | ❌ 不可以 |
| 链式调用 | base(...) 必须在构造函数第一行 | this(...) 也必须在构造函数第一行 |
base 和 this 的示例csharp
public class BaseClass
{
public BaseClass(string message)
{
Console.WriteLine($"Base: {message}");
}
}
public class DerivedClass : BaseClass
{
public DerivedClass() : this("默认参数") // this 调用本类另一个构造函数
{
Console.WriteLine("Derived: 无参构造函数");
}
public DerivedClass(string param) : base(param) // base 调用基类构造函数
{
Console.WriteLine($"Derived: {param}");
}
}
// 使用
DerivedClass obj = new DerivedClass();
// 输出:
// Base: 默认参数
// Derived: 默认参数
// Derived: 无参构造函数
base 的场景构造函数链:在派生类构造函数中初始化基类部分
扩展基类功能:在重写方法中调用基类实现,然后添加额外逻辑
解决命名冲突:当派生类隐藏基类成员时,仍需要访问基类版本
多层继承中跳过中间层:base 只能直接访问父类,不能跳过
访问虚方法的基类实现:虽然可以,但要考虑设计是否合理
base 只能访问直接基类csharp
class A { public virtual void M() { } }
class B : A { public override void M() { } }
class C : B
{
public override void M()
{
base.M(); // 调用 B.M(),不是 A.M()
// base.base.M(); // ❌ 编译错误
}
}
csharp
class Base { private int secret; }
class Derived : Base
{
void Test()
{
// int x = base.secret; // ❌ 编译错误:不可访问
}
}
base 调用(因为抽象方法没有实现)csharp
abstract class Base { public abstract void M(); }
class Derived : Base
{
public override void M()
{
// base.M(); // ❌ 编译错误:不能调用抽象方法
Console.WriteLine("实现");
}
}
base 关键字是派生类访问基类成员的通道:调用基类构造函数完成初始化、在重写方法中保留基类行为、或访问被隐藏的原始成员。它与 this 形成对称——this 指向自己,base 指向父辈。
本文作者:ZeroEngineer
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!