c# - 为什么这有时意味着基础?

标签 c#

给定

public class Animal
{
    public Animal()
    {
        Console.WriteLine("Animal constructor called");
    }
    public virtual void Speak()
    {
        Console.WriteLine("animal speaks");
    }
}

public class Dog: Animal
{
    public Dog()
    {
        Console.WriteLine("Dog constructor called");
        this.Speak();
    }
    public override void Speak()
    {
        Console.WriteLine("dog speaks");
  base.Speak();
    }
}

this.Speak() 调用 Dog.Speak()。从 dog 中删除 Speak() 并突然 this.Speak() 调用 Animal.Speak()。为什么 this 会这样?换句话说,为什么 this 表示 basethis

对我来说,显式调用 base.Speak() 更有意义。特别是当 speak 不是虚拟的时,令人惊讶的是,当 virtual 被移除时 Speak() 仍然被调用。我从 OO 的角度理解 IS-A 关系,但我无法解决 C# 中的这个特定问题。当人们编写上帝级 UI 时(实际上每个企业都这样做),这会变得特别烦人。当我应该查看“base”时,我正在“this”中寻找“Speak()”。

最佳答案

子类自动从它们的基类继承行为。如果除了从 Animal 继承 Dog 之外什么都不做,那么 this.Speak()base.Speak() 都引用了 Animal 中实现的 Speak() 版本。

如果 Dog 覆盖了 Speak(),就会开始发生特殊的事情。这是不可能的,除非 Speak()virtual。 (virtual 关键字不控制继承,它控制覆盖。)

只有当 Dog 覆盖 Speak() 时,base.Speak() 才会做一些特别的事情:在这种情况下,调用 Speak ()(或this.Speak())将执行Dog的实现,因为它覆盖Animal 的实现。这就是 base 变得有用的地方:它允许您通过指定要执行基类的实现而不是覆盖来绕过此行为。

此样式的常见用途是在构造函数中。例如:

public class Animal
{
    private readonly string _name;
    public Animal() : this("Animal") { }
    protected Animal(string name) { _name = name; }
    public void Speak() { Console.WriteLine(_name + " speaks"); }
}

public class NamedAnimal : Animal
{
    public NamedAnimal(name) : base(name) { }
}

// usage:
(new Animal()).Speak();  // prints "Animal speaks"
(new NamedAnimal("Dog")).Speak();     // prints "Dog speaks"

在此示例中,NamedAnimal 无法访问 _name 字段,但它仍然可以通过调用基类的构造函数来间接设置它。但是基类的签名与基类中的签名相同,所以必须使用base来指定。

对于非构造函数,获取无法以其他方式访问的行为也很有用。例如,如果 Animal.Speak 是虚拟的,那么我们可以使用覆盖将行为附加到它上面,而不是简单地替换它:

public class NamedAnimal : Animal
{
    public NamedAnimal(name) : base(name) { }
    public override Speak()
    {
        Console.Write("The animal named ");
        base.Speak();
    }
}

// usage:
(new NamedAnimal("Dog")).Speak();  // Writes "The animal named Dog speaks"

关于c# - 为什么这有时意味着基础?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10823720/

相关文章:

c# - 你会如何制作一个 "Favorite Pages"系统

c# - HttpWebRequest 虚拟按钮点击

c# - Win 窗体渐变背景和调整大小 c#

c# - IIS 花费大量时间来交付第一个 javascript 和图像文件

c# - 为什么类型推断不能根据约束确定类型

c# - 如何折叠空的 xml 标签?

c# - NetworkStream不支持查找操作

c# - 启动应用程序时发生错误。 InvalidOperationException : Scheme already exists: Identity. 应用程序

c# - 无法从接口(interface)实现类访问接口(interface)文档

c# - 如何在 C# 中的字符串列表中获取 "unordered choose two"排列