The*_*ble 0 c# virtual-functions
我可以理解基本的对象切片,但有时当我们来到这样的例子时它会变得很混乱
using System;
class A
{
public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
public override void F() { Console.WriteLine("D.F"); }
}
class Test
{
static void Main() {
D d = new D();
A a = d;
B b = d;
C c = d;
a.F();
b.F();
c.F();
d.F();
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
B.F
B.F
D.F
D.F
Run Code Online (Sandbox Code Playgroud)
我想知道如何达到B类的"f()"函数
D d = new D();
A a = d;
a.F();
Run Code Online (Sandbox Code Playgroud)
如果它是:
A a = new A();
a.F()
//The result would be => A.F
Run Code Online (Sandbox Code Playgroud)
但是在第一部分中,"a"的运行时间对象为"d",因此人们可能认为它是"DF"作为输出,所以它是如何出现在D和c以及B所以正确的输出是"BF"请帮我解决这个问题
当您使用new定义与基类的方法同名的方法时,您隐藏了基类的实现。(这几乎总是一个坏主意,但偶尔有必要。)
当您使用这样的隐藏方法引用类时,它不是覆盖。因此,您用来引用对象的变量类型将决定您将获得哪个版本的方法。
当您new D()通过a或引用您的任何一个时b,您将其引用为一种不知道new该方法版本的类型。因此,这两个调用都使用他们所知道的方法的最派生版本。不存在用于覆盖B.F()在任一C(因为它new)或D(因为它仅覆盖的方法C)。因此,B.F()在这两种情况下都被调用。
当您通过c或引用类时d,将使用覆盖的方法 in D,正如您所期望的。
嗯,AMAIK,你的问题基本上不是关于对象切片.它更多的是区别使用之间new,virtual和override关键字.
我将提出一个更容易理解的例子.考虑以下代码:
public class Animal
{
public virtual void Sleep()
{
Console.WriteLine(@"I'm an animal, and I want to sleep.
I just close my eyes");
}
}
public class Mammal : Animal
{
public override void Sleep()
{
Console.WriteLine(@"I'm a mammal, thus basically an animal.
Therefore, I both close my eyes, and need a warm place to sleep");
}
public bool HasBreasts
{
get
{
return true;
}
}
}
public class Human : Mammal
{
public new virtual void Sleep()
{
Console.WriteLine(@"I'm a human.
I'm so proud that I don't consider myself as an animal.
I sleep in a cozy place,
and I need a lot of money to sleep well");
}
public virtual void FallInLove();
}
public class Worker : Human
{
public override void Sleep()
{
Console.WriteLine(@"I'm a worker, and I'm under poverty line.
I have to work hard,
and I really don't know what they mean by a good sleep");
}
public override void FallInLove()
{
Console.WriteLine(@"What is love?
I need bread to survive.
I'm in the bottom-most level of Mozlow's pyramid of needs.");
}
}
Run Code Online (Sandbox Code Playgroud)
现在让我们分析每个关键字.由于a Worker基本上和基本上是人类,因此它HasBreasts也可以FallInLove().但是等一下.一个工人(没有冒犯,只是一个有趣的例子)没有钱坠入爱河.然后一个工人可能override会这样做,忘记爱情.
另一方面,所有动物都可以睡觉.他们只是闭上眼睛睡觉.然而,由于哺乳动物是热血动物,它们需要一个温暖的地方.所以他们延长了祖先的睡眠习惯.
但另一方面,人类定义了一个完全new水平的睡眠.他想要对他的祖先进行革命.他不想被称为Animal,所以他Sleep()从头开始重新定义.
现在根据@DanPuzey的解释,您可以阅读其余的故事.它在现实世界中是有意义的.
| 归档时间: |
|
| 查看次数: |
1820 次 |
| 最近记录: |