0

我在 C# 多态性中从 MSDN 资源中选择了这个代码。

public class A
{
    public virtual void DoWork() { }
}
public class B : A
{
    public override void DoWork() { }
}

public class C : B
{
    public override void DoWork()
    {
        // Call DoWork on B to get B's behavior:
        base.DoWork();

        // DoWork behavior specific to C goes here:
        // ...
    }
}

它说 C 类覆盖 B 的 DoWork(),但 B 类的 DoWork() 方法不是虚拟的。既然 C 继承了 B 的所有方法和数据,那么它是否也继承了 A 的虚方法(在 B 中可用,因为 A 是 B 的基类)?

如果 B 不提供 DoWork() 的实现,那么 C 会直接访问 A 的虚拟方法的副本以覆盖它吗?

此外,当 C 从 B 继承时,它会获得 A 成员的单独副本还是 B 成员的副本。我想对于 A 成员的单独副本,必须单独继承 A,例如

public class C : A, B

如果错了请纠正我。

编辑 :

public class A 
{ 
    public virtual void DoWork() 
    { 
        Console.WriteLine("In Class A");  
    }
} 
public class B : A 
{ 
    public void DoWork() { Console.WriteLine("In Class B"); } 
} 
public class C : B 
{ 
    public void DoWork() 
    { 
        Console.WriteLine("In Class C"); 
        base.DoWork(); 
    } 
} 

当我在 VS C# 上运行它时,不需要虚拟关键字。在 B 类的 DoWork() 中,并在 B 类和 C 的 DoWork() 中覆盖关键字,因为它只生成一个提示警告。那么这是否意味着只指定在类名定义中派生哪个基类,就像在公共类 C 中一样:B 足以使他的方法在本质上是虚拟的?

此外,由于 C# 不提供类的多重继承选项,有没有办法直接使用 C 类中 A 的 DoWork() 实现,而不显式创建 A 的对象,然后使用它访问 DoWork()?

4

2 回答 2

6

它说 C 类覆盖 B 的 DoWork(),但 B 类的 DoWork() 方法不是虚拟的。

当你重写一个虚拟方法时,它“保持”虚拟,除非你明确地用sealed. (如果它也是覆盖方法,则只能为方法指定修饰符。)sealed

如果 B 不提供 DoWork() 的实现,那么 C 会直接访问 A 的虚拟方法的副本以覆盖它吗?

是的。或者更确切地说,它会在执行时调用 A 的实现。它不是真正的“副本”。

此外,当 C 从 B 继承时,它是否会获得 A 成员的单独副本

你在这里的意思不是很清楚。你在说什么样的“副本”,哪些成员?如果您的意思是每个对象中有哪些字段,那么它只是继承链上所有类中声明的字段的联合。

编辑:在您编辑的代码中,您没有覆盖任何内容。您正在声明方法,这些方法不是以多态方式调用的。所以如果你写:

A a = new C();
a.DoWork();

这将只打印“In Class A” - 而如果BC 覆盖虚拟方法,它将打印“In Class C”,然后打印“In Class B”。

此外,由于 C# 不提供类的多重继承选项,有没有办法直接使用 C 类中 A 的 DoWork() 实现,而不显式创建 A 的对象,然后使用它访问 DoWork()?

B假设这是在overrides的情况下DoWork,不。这会破坏封装 -B例如,它可能会破坏 的不变量。

于 2013-06-05T06:38:12.367 回答
1

C is inheriting from B, this means it can override all virtual methods in B. Override means method is still virtual.
If B would not give any implementation for DoWork, then base.DoWork in C's implementation would call the implementation in A class - as normally virtual behaves. You should not assume that your base call will be call to exactly B method and no other - it's implementation detail that could be changed in future. Important thing is it will call nearet parent implementation of DoWork.

And finally - when inheriting B, you also get all the properties, methods and everything inherited from A. In C# there is nothing like multiple inheritance (meaning C : A, B where C, A and B are classes will not work). You cannot get separate copy or anything of A with inheritance - you just get what's in B (which of course includes things that B has inherited from A and so on).

于 2013-06-05T06:43:19.860 回答