如果您有基类
public abstract class AbsHashtableish<TKey, TValue>
{
public abstract TKey ConvertToKey(string key);
public abstract bool KeyExists(TKey key);
public virtual bool KeyExists(string key)
{
Console.WriteLine("In Base");
return KeyExists(ConvertToKey(key));
}
}
和一个概念类
public class ConcreteHashtableish: AbsHashtableish<string, Dinosaur>
{
...
public override string ConvertToKey(string key)
{
return key;
}
public override bool KeyExists(string key)
{
Console.WriteLine("In Sub");
return _list.Contains(key);
}
}
和客户A
AbsHashtableish<string, Dinosaur> concreteA = new ConcreteHashtableish<string, Dinosaur>();
和客户B
ConcreteHashtableish<string, Dinosaur> concreteB = new ConcreteHashtableish<string, Dinosaur>();
用于确定上面显示的代码是否足以编译的规则(如果可能,背后的原因)是什么规则,如果是这样的话:
KeyExists
与concreteA
之间调用concreteB
之间是否存在差异?KeyExists(string key)
,我们能够摆脱它吗?对于问题#2,我的意思是,如果编译器能够以某种方式编译此代码,它是否通过有效地从客户端隐藏基本方法来实现 - 因为如果达到该代码,则会导致无限循环?
答案 0 :(得分:2)
在KeyExists
和convreteA
上拨打concreteB
最终都是一样的。
Common Language Runtime (CLR)
知道调用实际类型的方法(使用Virtual Method Table)。这是Polymorphism的重点。它允许您将具体实现称为抽象实现,但实际调用的方法是具体类型。
在您给出的特定示例中,您不能在派生类之外使用KeyExists
的基类实现,只是因为您无法创建抽象类的实例。如果它不抽象,你可以创建:
AbsHashtableish<string, Dinosaur> baseA = new AbsHashtableish<string, Dinosaur>();
AbsHashtableish.KeyExists
将被调用。
编辑:(感谢Oliver注意到)
您始终可以从派生类内部调用基类实现。在这种情况下,您可以致电:
base.KeyExists(key)