【问题标题】:Polymorphism and c#多态性和c#
【发布时间】:2010-03-16 15:10:16
【问题描述】:

最近在MS面试中又问了一个基本问题

class A {
    public virtual void Method1(){}

    public void Method2() {
        Method1();
    }
}

class B:A {
    public override void Method1() { }
}

class main {
    A obk = new B();
    obk.Method2(); 
}

那么调用了哪个函数?错别字见谅。

【问题讨论】:

  • 你为什么不试试看?
  • @Jeff:没关系; B.Method1() 仍然是被调用的函数。
  • 我认为根据 VMT(Vitual Method Table),将调用被覆盖方法的最新版本。所以它可能是 B.Method1()

标签: c# polymorphism


【解决方案1】:
B.Method1();

被调用是因为它正确地覆盖了虚拟方法A.Method1();

【讨论】:

    【解决方案2】:

    在这种情况下,B.Method1 被调用。这是因为即使变量类型为A,实例的实际类型也是B。 CLR 根据实例的实际类型而不是变量的类型多态地分派对Method1 的调用。

    【讨论】:

      【解决方案3】:

      B 中的Method1 将被调用,运行以​​下程序可以看到:

      class Program
      {
          static void Main(string[] args)
          {
              var b = new B();
              b.Method2();
      
              Console.ReadLine();
          }
      }
      
      class A 
      { 
      
          public virtual void Method1()
          {
               Console.WriteLine("Method1 in class A");
          } 
      
          public void Method2() 
          { 
               Method1(); 
          } 
      }
      
      class B : A 
      { 
          public override void Method1() 
          { 
               Console.WriteLine("Method1 in class B"); 
          } 
      } 
      

      【讨论】:

        【解决方案4】:

        规则是“覆盖最派生类中的成员”,在本例中为“B”。

        【讨论】:

          【解决方案5】:

          由于覆盖而调用了 B.Method1()。

          【讨论】:

            【解决方案6】:

            B.Method1 被调用是因为它在类定义中被覆盖。

            【讨论】:

              【解决方案7】:

              这个问题有点模棱两可……但是……

              obk.method2() 被调用。反过来,它调用 obk.Method1,因为它是 B 的一个实例,所以它已被 B.Method1 覆盖。所以最终会调用 B.Method1。

              【讨论】:

                【解决方案8】:

                正如其他人所说,B.Method2 被调用。以下是一些其他信息,以便您了解发生了什么:

                ((A)B).Method2();
                B.Method2();
                

                这些都将调用 B.Method1() 因为它被正确地覆盖了。为了调用 A 的 Method1,必须有一个从 B 发出的 base.Method1() 调用(在 B.Method1 的实现中经常但并不总是这样做)。

                但是,如果 B 以这种方式定义:

                class B:A {
                new public void Method1() { }
                

                ... 然后 A 的 Method1() 将被调用,因为 Method1 实际上并未被覆盖,它在多态性规则之外隐藏并隐藏。一般来说,这通常是一件坏事。并非总是如此,但如果您做过类似的事情,请确保您非常清楚自己在做什么以及为什么要这样做。

                另一方面,以这种方式使用 new 也会产生一些有趣的面试问题。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2017-01-02
                  • 2012-10-11
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-05-25
                  相关资源
                  最近更新 更多