使用 Virtual/Override 方法从铸造引用访问对象

Accessibility to an object from a casting reference using a Virtual/Override method

使用来自子类引用的引用,它的可访问性如何表现,因为它们是虚拟的?

假设这个例子:

public class Asset {
    public string name;
    public virtual decimal Liability {get {return 0;} }
}

public class House : Asset {
    public decimal Mortgage;
    public override decimal Liability {get {return Mortgage;} }
}

House mansion = new House {name = "SomeName", Mortgage = 100000};
Asset a = mansion;
print (mansion.Liability);      // 100000
print (a.Liability);            // 100000 (not 0!)

我认为 a.Liability 会显示 0,因为它是 Asset 类型的引用,考虑到它在上一个转换中的可访问性。

因为您创建了一个子class House,其中 Liability 以多态方式被覆盖,甚至从一个角度访问引用 a Asset 将深入到 subclass 因为 Liability 在基础 class 中被声明为 virtual 并且这是你通常想要的行为(如果你想使用多态性)。

想象一个 List<Asset>,其中每个实例都是 Asset 的不同子类型。你不想关心子类型,但你想 "just access" Liability 属性 并始终根据具体实例获得正确的值。那就是多态。

如果您使用 new 而不是覆盖 House.Liability,您将得到 0 作为结果。因为 new 会破坏继承链。因此,从 Asset 的引用来看,您只会看到 Asset.Liability(因为其他所有内容 "beyond" 由于子 class 中的 new 而被隐藏)。但是如果您从 House 的引用中查看,您会看到 House.Liability。那已经不是多态了。

也许 Polymorphism 会更好地阐明这一点 ;-)

这很正常,甚至是多态性的原理。如果你希望结果 = 0,你必须删除虚拟我猜这不是你的开始意图,或者你必须构造对象 'Asset'。如下:

 House mansion = new House { name = "SomeName", Mortgage = 100000 };
            Asset a = new Asset { name = "SomeName" };
            Console.WriteLine(mansion.Liability);      // 100000
            Console.WriteLine(a.Liability); //0 OK

如果没有虚的话,你说的是真的。您期望的行为通过以下代码呈现:

public class Asset
{
    public string name;
    public decimal Liability { get { return 0; } }
}

public class House : Asset
{
    public decimal Mortgage;
    public decimal Liability { get { return Mortgage; } }
}

House mansion = new House { name = "SomeName", Mortgage = 100000 };
Asset a = mansion;
Console.WriteLine(mansion.Liability);      // 100000
Console.WriteLine(a.Liability); //0 OK