从基本构造函数调用重写的方法
我们有一个这样的类:
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# 中测试了它,重写的方法有效,但我怀疑在解释语言中可能是相反的情况。这是真的吗?
We have a class like this:
class LogAnalyzer
{
protected IExtensionManager manager;
public LogAnalyzer()
{
GetManager();
}
protected virtual void GetManager()
{
manager = new FileExtensionManager();
}
}
And we derive another class like this:
class TestableLogAnalyzer:LogAnalyzer
{
protected override void GetManager()
{
this.manager = new StubExtensionManager();
}
}
When we instantiate the child class what's supposed to happen in OOP rules? Does the virtual or the overridden method gets called and why? I tested it in C# and overridden method worked but I suspect it may be the other way around in an interpreted language. Is that true?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对此提供与语言无关的答案并不简单,因为“发生了什么”取决于语言本身。例如,在 Java 中,将调用重写的(虚拟)方法,但这可能会带来其自身的问题,因此不建议这样做。
您需要查阅您感兴趣的文档或语言规范,然后四处阅读,看看是否有人发表了关于为什么您应该或不应该这样做以及可能会出现什么问题的意见,例如 Scott Meyers 的文章AraK 在他/她的评论中链接到。
It's not simple to provide a language agnostic answer to this, because "what happens" depends on the language itself. In Java, for instance, the overridden (virtual) method will be called, but this can present its own problems, and is thus not recommended.
You need to consult the documentation or language specification you're interested in, and then read around to see if anyone's published an opinion on why you should or shouldn't do it, and what might go wrong, such as the Scott Meyers piece that AraK links to in his/her comment.
由于它与语言无关,我将使用 C++ 作为基础,并希望可以推断出这些建议。
LogAnalyser 的构造函数在 TestableAnalyser 的构造函数之前调用。这意味着在工作期间 TestableAnalyser 尚未构造,因此调用虚拟方法可能是危险的(它们可能使用未初始化的数据)。
在您的情况下,派生类想要影响其基类的初始化。虚拟方法重写并不是实现此目的的唯一方法。您可以再创建一个接受管理器的构造函数,派生类将传递“new StubExtensionManager();”。
Since it's language agnostic, I'll use C++ as a base and will hope that the advice can be extrapolated.
Constructor of LogAnalyser is called before constructor of TestableAnalyser. This means that during its work TestableAnalyser is not constructed yet, thus calling virtual methods can be dangerous (they may use uninitialized data).
In your case derived class wants to affect initialization of its base class. Virtual methods overriding is not the only way to do this. You can create one more constructor which accepts manager, derived classes will pass "new StubExtensionManager();".