How to “properly” override a base class method?

自闭症网瘾萝莉.ら 提交于 2019-11-30 01:21:16

how could a child class know (without taking a look at base class implementation) which order (or option) is being expected by the parent class?

There is no way to "know" this when you are subclassing and overriding a method. Proper documentation is really the only option here.

Is there a way in which parent class could enforce one of the three alternates to all the deriving classes?

The only option here is to avoid the issue. Instead of allowing the subclass to override the method, it can be declared non-virtual, and call a virtual method in the appropriate place. For example, if you want to enforce that subclasses "call your version first", you could do:

public class BaseClass {
    public void Method() // Non-virtual
    {
          // Do required work

          // Call virtual method now...
          this.OnMethod();
    }

    protected virtual void OnMethod()
    { // Do nothing
    }
 }

The subclasses can then "override" OnMethod, and provide functionality that happens after "method"'s work.

The reason this is required is that virtual methods are designed to allow a subclass to completely replace the implementation of the parent class. This is done on purpose. If you want to prevent this, it's better to make the method non-virtual.

This is why I feel virtual methods are dangerous when you ship them in a library. The truth is you never really know without looking at the base class, sometimes you have to fire up reflektor, read documentation or approach it with trial and error.

When writing code myself I've always tired to follow the rule that says:

Derived classes that override the protected virtual method are not required to call the base class implementation. The base class must continue to work correctly even if its implementation is not called.

This is taken from http://msdn.microsoft.com/en-us/library/ms229011.aspx, however this is for Event design though I believe I read this in the Framework Design Guidelines book (http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321246756).

However, this is obviously not true, ASP.NET web forms for example require a base call on Page_Load.

So, long and short, it varies and unfortunately there is no instant way of knowing. If I'm in doubt I will omit the call initially.

The short answer is no. You can't enforce in what order the child calls the base method, or if it calls it at all.

Technically this information should be included in the base object's documentation. If you absolutely must have some code run before or after the child class' code than you can do the following:

1) Create a non-virtual function in the base class. Let's call it MyFunction

2) Create a protected virtual function in the base class. Let's call it _MyFunction

3) Have deriving classes extend the _MyFunction method.

4) Have MyFunction call _MyFunction and run the code it needs to run before or after calling it.

This method is ugly and would require a lot of extra code, so I recommend just putting a notice in the documentation.

The requirements of the base class should be documented by the library designer. This issue is the reason why some libraries contain mainly sealed classes.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!