我是C#新手,我不明白编译器为什么不抱怨这段代码。以下是类的层次结构:
interface IAble
{
void f();
}
class AAble : IAble
{
public void f()
{
Debug.Log("---->> A - Able");
}
}
class BAble : AAble
{
public void f()
{
Debug.Log("---->> B - Able");
}
}
执行代码:
IAble i = new BAble();
i.f();
执行时<代码>----
当决定调用什么函数时--运行时还是编译时?如果我弄脏了一个新的< code>class CAble : IAble怎么办?
接口必须在直接继承自它的类中实现,而不是在派生类中实现。例如,此代码无法编译:
class AAble : IAble
{
public void f() { ... }
}
class BAble : AAble
{
// An attempt to explicitly implement interface in BAble through AAble class
void IAble.f()
{
Console.WriteLine("---->> B - Able");
}
}
当我们向上转换 BAble
以接口 IAble 时,将使用来自 AAble
的实现,因为它是编译预期中唯一实现该接口的类。
我们可以直接从接口继承,这将告诉编译器应该使用哪个接口实现:
class BAble : AAble, IAble
{
// Now it compiles
void IAble.f()
{
Console.WriteLine("---->> B - Able");
}
}
输出:<代码>-
或者我们可以使用多态性。这将告诉编译器总是使用被覆盖的函数:
class AAble : IAble
{
public virtual void f()
{
Debug.Log("---->> A - Able");
}
}
class BAble : AAble, IAble
{
public override void f()
{
Console.WriteLine("---->> B - Able");
}
}
通常会有编译器警告,因为它隐藏了一个方法。但在C#中,对非虚拟函数这样做是合法的。当然,如果它是一个虚拟函数,那么显然该方法的B版本将运行。
因为你将它声明为一个可变量,并且它是非虚拟的,编译器将它读为一个可变量。如果它被声明为虚拟的,编译器将扫描继承的层次结构,并会看到它的实际类是BAble,它将运行BAble代码。
因为< code>AAble正在实现< code>IAble接口,所以它的< code>AAble.f被标记为类型< code>AAble的< code>IAble.f方法的实现。
< code>BAble.f只是隐藏了< code>AAble.f方法,而不是覆盖它。
IAble o = new BAble(); o.f(); // calls AAble.f
AAble o = new BAble(); o.f(); // calls AAble.f
BAble o = new BAble(); o.f(); // calls BAble.f
IAble o = new CAble(); o.f(); // calls CAble.f
决策是在编译时做出的:
// AAble.f in IL:
.method public final hidebysig newslot virtual
instance void f () cil managed
// BAble.f in IL:
.method public hidebysig
instance void f () cil managed
接口实现在IL中被标记为虚拟
,即使它在C#中没有被标记为虚拟。该方法在IL中也被标记为最终
,如果该方法在C#中是虚拟
,它就不会被标记为最终
。
让我们在Visual C 2010中假设以下场景: 理论上,这个小应用程序的输出应该是: 基本:非虚拟显示。 基础:虚拟显示。 基本:非虚拟显示。 派生:虚拟显示。 因为基类的显示方法不是虚拟方法,所以派生类不能重写它。正当 问题是,当我运行应用程序时,它会打印以下内容: < li >基本:非虚拟显示。 < li >基本:虚拟显示。 < li >派生:非虚拟显示。 < li >派生:虚拟显示。 所
问题内容: 我有一个定义方法的接口。我有一个 实现 此接口的结构。在其中,我已经从该接口实现了方法,并且还定义了其他方法。 例如: 在操场上:https : //play.golang.org/p/B1GgoNToNl_l 在此,WagTail()不是Animal接口的一部分,但属于Dog结构。运行此代码会出现错误 dog.WagTail未定义(动物类型没有字段或方法WagTail)。 有没有一种
问题内容: 我正在尝试获取一些信息,但我的应用程序崩溃并显示以下消息: 这是代码: 这是一个纯课。的哪个调用不包含this 。我做错了吗?应始终位于内吗? 根据要求整体: 问题答案: 改成 您为布局充气。视图属于膨胀的布局。因此,使用view对象在中初始化视图 片段由活动主持 您可以在视图中使用和初始化 还在中初始化TextView 。由于Asynctask是一个内部类,因此您可以在那里更新ui
问题内容: Java-8允许在接口内部定义静态方法,但仅通过接口名称限制其调用: 9.4:接口可以声明静态方法,这些方法在不引用特定对象的情况下被调用。 例如: 导致错误: 在JLS中,这种禁令经常有一种解释。在这种情况下,我没有发现任何详细信息。因此,我正在寻找对此规则的全面或权威的解释:为什么禁止通过特定的对象引用调用静态方法?它有什么坏处? 问题答案: 相当强烈的共识是,有关类的静态方法也不
所以,基本上我创建了一个包装器类,它创建了一个简单的OpenGL应用程序。我的想法是在准备好的时候有这样的东西: 所以,基本上这个类使用GLFW封装了一个简单的OpenGL窗口。这个想法是,当你想要创建一个新的应用程序时,你只需要从应用程序类(我正在写的)派生你的类。使用这个新类,您只需重写虚拟方法(main Loop、初始化和回调),您将拥有一个工作应用程序。 下面是基类: 所以我所做的是将在派
当我运行我的应用程序时,我有一个异常显示,所以我想帮助我:)异常是:java。lang.NullPointerException:尝试调用虚拟方法“int java”。lang.String。空对象引用上的长度() 当我单击Login类中的dd1按钮和按钮实现(public void getData(View v))方法时,会显示异常 非常感谢。 登录类 HttpManager类 日志: