C# 隐藏对象';来自编译器的类型
我在一次采访中被问到这个问题。这让我完全措手不及 你有一个超类和一个子类。类C# 隐藏对象';来自编译器的类型,c#,java,C#,Java,我在一次采访中被问到这个问题。这让我完全措手不及 你有一个超类和一个子类。类B是a的一个子类。两个类都实现了相同的函数foo() 是否可以编写一段代码,使编译器不知道对象的类型?在这种情况下,对象是下面的b A b = new B(); 然后,您将执行一个函数调用,在该调用中,直到执行时才知道类型 这是我在白板上的回答:(A)b.foo()您可以使用反射创建编译器不知道的某种类型的对象(只能在运行时解析) 如果您特别提到语句new B(),那么就不是——您是在告诉编译器正在创建的确切类型。至少
B
是a
的一个子类。两个类都实现了相同的函数foo()
是否可以编写一段代码,使编译器不知道对象的类型?在这种情况下,对象是下面的b
A b = new B();
然后,您将执行一个函数调用,在该调用中,直到执行时才知道类型
这是我在白板上的回答:
(A)b.foo()代码>您可以使用反射创建编译器不知道的某种类型的对象(只能在运行时解析)
如果您特别提到语句new B(),那么就不是——您是在告诉编译器正在创建的确切类型。至少在C语言中,您可以使用动态,编译器将在运行时输入代码来确定类型。在C语言中,您可以使用关键字来实现动态类型
public void MyMethod(dynamic myVar)
{
// The compiler don't know the exact type of myVar
// Does myVar have a foo() method? if not, we get a runtime error.
myVar.foo();
}
然而,我认为这不是他们想要的答案,因为提到了A
和B
(它应该同时适用于Java和C)
他们可能一直在寻找的(基本上是你自己说的)可能是这样的:
public void MyMethod(A a)
{
a.foo(); // What foo() method is called? The one from A or the one from B?
}
您可以使用A
和B
的实例作为MyMethod
的参数,因为B
与A
具有is-A关系(它继承)。编译器将a
视为a
的实例,即使它可能是B
的实例
调用了什么foo()
方法?这取决于B
是覆盖A
的foo()实现还是隐藏它。如果它将其隐藏,则调用一个
的方法,这是在编译时确定的,而与A真正拥有的类型无关
如果它覆盖了foo()
(很可能是这种情况),那么它将在运行时确定。由于编译器不知道a
的确切类型,因此在运行时根据a
的类型查找正确的调用方法
因此编译器确实知道类型(它是A
),但不知道确切的类型(它是不是子类?)
作为旁注<代码>(A)b.foo()
将从foo()
返回的值强制转换为A
。如果要在调用foo()
之前将b
强制转换为A
,则应添加一组额外的括号:((A)b).foo()代码>。但是,强制转换是不必要的,因为b
已经声明为A
变量(ab=..
)。我认为该方法是在运行时确定的……是的,这就是想法。我想知道为什么会投反对票。问题是关于哪种语言?Java或C#,这是该公司使用的两种语言。这就是为什么我的标签是[c#]和[java]。我不理解最后一句话。您所说的“…也许这样的东西不允许编译器知道类型:(A)b.foo();
”是什么意思?