c# - 会调用什么函数?

标签 c# interface

之前我问了一个没有完全回答的问题,因此我决定重新表述我的问题以了解发生了什么:

这是我的类层次结构:

interface I
{
    void f();
}

class A : I
{
    // non virtual method
    public void f()
    {
        Debug.Log("---->> A ");
    }
}

class B : A
{
    // non overriding but hiding class A method
    public void f()
    {
        Debug.Log("---->> B ");
    }
}

class C : I
{
    // non virtual method
    public void f()
    {
        Debug.Log("---->> C ");
    }
}

执行代码如下:

Random rnd = new Random();
var randomI = rnd.Next(0, 2);

I i = null;
if (randomI == 0)
{
     i = new B(); 
}
else
{
    i = new C();
}
i.f(); 

就目前而言,它会输出 A 或 C。它不会输出 B。

这里的问题是:您能否通过涵盖这些步骤来解释如何决定调用哪些函数?

  1. 何时决定调用哪个函数 - 运行时还是编译时?
  2. 决定调用什么函数的机制是什么?

最佳答案

在编译时它会调用I 接口(interface),然后在运行时它会调用继承链中实现I.f() 的顶级方法。

所以,在你的代码中这个

A a = new A();
a.f();

B b = new B();
b.f();

将使编译器执行以下指令:

  • 创建类 A 的实例并分配给“a”
  • 获取分配给“a”的对象并调用位于继承链顶部并实现A.f() 的方法。在这种情况下是 A.f() 本身
  • 创建B类实例并赋值
  • 获取分配给“a”的对象并调用位于继承链顶部并实现B.f() 的方法。在这种情况下是 B.f() 本身

结果为“A”和“B”。

但是,当你这样做时:

I i;
i = new B();
i.f();

你让它编译以下指令:

  • 声明一个变量“i”
  • 创建一个新的对象 B 并将其赋值给“i”
  • 获取分配给“i”的对象并调用位于继承链顶部并实现I.f() 的方法。是A.f(),因为类B没有实现接口(interface)I

i.f() 行,它不知道 new B() 被分配给 i,它可能是从某个地方传递的别的。它只知道有一些抽象对象实例实现了 I 并且它需要调用它的 f() 方法。

您可以将 方法视为具有不同名称 的方法:

public class B : A
{
    // non overriding but hiding class A method
    public void anotherName()
    {
       Debug.Log("---->> B ");
    }
} 

A a = new A();  
a.f();
B b = new B();
b.anotherName();

I i = new B();
i.f(); // this will obviously call the `A.f()` because there is no such method in B

唯一的区别是您不能为继承的类实例调用隐藏方法。

关于c# - 会调用什么函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52204649/

相关文章:

java - 接口(interface)定义包含对其他接口(interface)的引用是否可以接受?

interface - Go接口(interface)/容器使用

c# - Azure 实例 0 到 3 未在 WadPerformanceCountersTable 中写入诊断数据

c# - Mongo C# 驱动程序 - 长度支持?

dictionary - 接受多种接口(interface)类型的数据类型

objective-c - Cocoa 从子类实例移动到父类

c# - 为什么我应该返回 IList<T> 而不是 List<T>?

c# - ReadLine与磁盘访问的关系

c# - 如何更改查询字符串参数的值?

c# - 具有异步套接字的C#游戏客户端