为什么这有时意味着基数?

时间:2012-05-30 20:24:41

标签: 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()。从狗身上移除Speak(),然后突然this.Speak()来电Animal.Speak()。为什么this表现得这样?换句话说,为什么this表示basethis

对我来说,明确调用base.Speak()会更有意义。特别是当说话不是虚拟时,令人惊讶的是,当virtual被删除时仍然会调用Speak()。我从OO意义上理解IS-A关系,但我不能在C#中解决这个特定问题。当人们编写神级UI(几乎每个企业都这样做)时,这尤其令人讨厌。我正在寻找“this”里面的“Speak()”当我应该看“base”。

5 个答案:

答案 0 :(得分:3)

不是那样的。如果 dog中的发言方法,那么它就是基本方法的 override 。如果它不存在,则调用dogInstance.Speak将在Dog的任何基类中查找Speak()方法。

答案 1 :(得分:3)

子语句自动从其基类继承行为。如果您从Dog继承Animal以外的任何内容,那么this.Speak()base.Speak()都会引用Speak()中实现的Animal版本}}

如果Dog覆盖Speak(),则特殊事情开始发生。除非Speak()virtual,否则无法执行此操作。 (virtual关键字不控制继承,它控制覆盖。)

仅当Dog覆盖Speak() base.Speak()时才会执行特殊操作:在这种情况下,调用Speak()(或this.Speak())将执行{{1} }的实现,因为Dog override的实现。这是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

答案 2 :(得分:2)

这是OO的基本要点之一。如果您不提供覆盖,则使用父方法。

此外,即使您删除了virtual,也会调用Dog.Speak,因为您没有以多态方式访问this

答案 3 :(得分:1)

this表示this,而不是其他任何内容。

在第一个示例中,您有Speak(..)函数的覆盖,因此this会调用该函数。

在第二种情况下,没有任何覆盖,所以它“爬上”派生树并选择第一个合适的函数。在您的情况下,其中一个是Speak(..)的{​​{1}}。

答案 4 :(得分:0)

VB.Net只有MyClass关键字(而不是My关键字,相当于C#中的this。不幸的是,C#中没有MyClass个等效关键字。