1

好的,可以说我有两个具有相同方法(sampleMethod)的类,它们被孩子覆盖:ObjectParent 和 ObjectChild

ObjectChild ExampleVariable = new ObjectChild();
(ExampleVariable as ObjectParent).sampleMethod();

这会从 ObjectChild 还是从 ObjectParent 调用 sampleMethod?

我认为它会从 ObjectChild 调用 sampleMethod,但我想在基于该假设丢掉一堆代码之前确定一下。

4

5 回答 5

2

如果它被覆盖(而不是隐藏),那么在运行时将使用子类的实现。这是多态性的要点之一。您不需要知道对象的实际运行时类型是什么,并且可以将其视为基类的实例。

于 2012-11-07T07:49:46.743 回答
1

正如 Jon Skeet 所说......“假设它确实是一个被正确覆盖(而不是仅仅被隐藏)的虚拟方法,它将调用 ObjectChild 实现。”

这里假设你在父类的方法之前使用了 virtual 关键字,在子类的方法之前使用了 override 关键字。

否则......有两件事需要考虑:

  1. 父类的方法是否只是被隐藏。要调查此类案件..请查看以下链接:http: //msdn.microsoft.com/en-us/library/ms173153.aspxhttp://msdn.microsoft.com/en-us/library/ 6fawty39.aspx

  2. 提供给方法的访问级别(有时在父级和子级中可能不同)。override 方法和 virtual 方法都必须具有相同的访问级别修饰符,但如果您没有使用这些修饰符,则可以选择。

只有经过以上考虑,我们才能得出有关情况的结论。

于 2012-11-07T08:14:17.347 回答
1

这会从 ObjectChild 还是从 ObjectParent 调用 sampleMethod?

假设它确实是一个被正确覆盖(而不是仅仅被隐藏)的虚拟方法,它将调用ObjectChild实现。这就是虚方法的全部意义——你不需要在编译时知道执行时的类型。例如,我可以使用Stream.Read(例如,将Stream用作参数)编写一个方法,而不知道它最终将使用哪个实现Stream在执行时,代码最终可能会从网络、内存、磁盘读取……我的方法的代码既不知道也不知道大小写。

简短但完整的程序演示了这一点:

using System;

class ObjectParent
{
    public virtual void Foo()
    {
        Console.WriteLine("ObjectParent.Foo");
    }
}

class ObjectChild : ObjectParent
{
    public override void Foo()
    {
        Console.WriteLine("ObjectChild.Foo");
    }
}

class Test
{
    static void Main()
    {
        // Simpler code to demonstrate the point
        ObjectParent parent = new ObjectChild();
        parent.Foo(); // Prints ObjectChild.Foo
    }
}
于 2012-11-07T07:50:17.610 回答
1

这取决于您的 sampleMethod 是否是virtualoverriden.. 那么是的。但也可能有:

ObjectParent ExampleVariable = new ObjectChild();
ExampleVariable.sampleMethod();

virtual表示此方法是多态的,可以被派生类型覆盖。overridden意味着派生类在这种情况下实际上从基类覆盖了 sampleMethod 的实现。我想答案就在关键字本身中。

于 2012-11-07T07:51:10.970 回答
1

是的,它调用ObjectChild.sampleMethod(),因为您可以轻松地测试:

class ObjectParent
{
    public virtual void sampleMethod()
    {
        Console.WriteLine("Parent");
    }
}

class ObjectChild : ObjectParent
{
    public override void sampleMethod()
    {
        Console.WriteLine("Child");
    }
}
于 2012-11-07T07:51:37.013 回答