我们有一个这样的课程:
class LogAnalyzer
{
protected IExtensionManager manager;
public LogAnalyzer()
{
GetManager();
}
protected virtual void GetManager()
{
manager = new FileExtensionManager();
}
}
我们得到了另一个这样的类:
class TestableLogAnalyzer:LogAnalyzer
{
protected override void GetManager()
{
this.manager = new StubExtensionManager();
}
}
当我们实例化子类时,应该在OOP规则中发生什么?虚拟或重写的方法是否被调用,为什么?我在C#中进行了测试,并且覆盖了方法,但我怀疑它可能是解释语言的另一种方式。这是真的吗?
答案 0 :(得分:1)
提供与语言无关的答案并不简单,因为“会发生什么”取决于语言本身。例如,在Java中,将调用重写的(虚拟)方法,但这可能会出现问题,因此不建议这样做。
您需要查阅您感兴趣的文档或语言规范,然后阅读以了解是否有人发表了关于您为什么应该或不应该这样做的意见,以及可能出现的问题,例如Scott在他/她的评论中,AraK链接到的Meyers片段。
答案 1 :(得分:1)
由于它与语言无关,我将使用C ++作为基础,并希望可以推断出这些建议。
在TestableAnalyser的构造函数之前调用LogAnalyser的构造函数。这意味着在其工作期间TestableAnalyser尚未构建,因此调用虚方法可能很危险(它们可能使用未初始化的数据)。
在您的情况下,派生类希望影响其基类的初始化。虚拟方法覆盖不是执行此操作的唯一方法。您可以再创建一个接受管理器的构造函数,派生类将传递“new StubExtensionManager();”。