任何人都可以向我解释为什么它会这样做。输出结果为"Print This"
。但是,如果没有实现,基类如何调用bar()
。
abstract class Base
{
protected virtual void foo()
{
bar();
}
protected abstract void bar();
}
class Sub : Program
{
protected override void foo()
{
base.foo();
}
protected override void bar()
{
Console.WriteLine("Print This");
}
static void Main(string[] args)
{
Sub obj = new Sub();
obj.foo();
}
}
答案 0 :(得分:3)
这是抽象类的重点:它只会作为派生类的实例具体存在。通过声明抽象方法或属性,它只是强制派生类提供这些成员的具体实现。这样,如果你有一个Base
类型的实例,你可以调用myInstance.bar
,你知道派生类已经实现了它,因为它不会编译。
顺便说一句,在命名方法时使用pascal case,即Foo
和Bar
。
答案 1 :(得分:0)
但是当没有时,基类如何调用bar() 实施
TL; DR 回答:因为多态。
如果你有这个问题,你怎么解释这个?
public interface IStuffMaker
{
void MakeIt();
}
public class StuffMaker : IStuffMaker
{
public void MakeIt()
{
Console.WriteLine("yeah!");
}
}
IStuffMaker maker = new StuffMaker();
maker.MakeIt();
为什么maker
IStuffMaker
可以致电MakeIt()
?因为StuffMaker
已经实现了所谓的方法。
在您的特定情况下,能够调用您的抽象方法的原因是因为抽象成员是多态并且派生类必须覆盖它以提供实现(与接口成员相同:必须实现它们。
抽象类是可能的具体成员(带有主体)和抽象类的混合,它们只是成员签名,如接口成员,但是,与接口相反,因为抽象类可以拥有具体成员,这些可以调用抽象的,因为它们将在派生类中实现。