Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to "properly" override a base class method?

Whenever i override a method of a base class, other than my implementation of this method, i seem to have 3 choices.

1) Call base.Method(), and then provide my implementation.

2) Provide my implementation and then call base.Method()

3) Just provide my implementation.

Recently while using a library i have realized few bugs that were introduced because of not implementing the method as expected by the library. I am not sure if that is bad on part of library, or something wrong in my understanding.

I will take one example.

public class ViewManager {
     public virtual void Customize(){
        PrepareBaseView();
     }
}

public class PostViewManager {
     public override void Customize(){
        base.Customize();
        PreparePostView();
     }
}


public class PreViewManager {
     public override void Customize(){
        PreparePreView();
        base.Customize();
     }
}


public class CustomViewManager {
     public override void Customize(){
        PrepareCustomView();
     }
}

My question here is that 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? Is there a way in which parent class could enforce one of the three alternates to all the deriving classes?

like image 480
Manish Basantani Avatar asked Jun 30 '10 20:06

Manish Basantani


People also ask

How do you override a base class property?

you can override properties just like methods. That is, if the base method is virtual or abstract. You should use "new" instead of "override". "override" is used for "virtual" properties.

Why would you override method of base class?

The main advantage of method overriding is that the class can give its own specific implementation to a inherited method without even modifying the parent class code.

Is it mandatory to override a base class method in inherited class?

Yes, you need to use the override keyword, otherwise the method will be hidden by the definition in the derived class. If you actually run your code, you will see "Shapes" printed twice.


3 Answers

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.

like image 147
Reed Copsey Avatar answered Oct 04 '22 00:10

Reed Copsey


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.

like image 39
nullable Avatar answered Oct 04 '22 02:10

nullable


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.

like image 30
Timothy Baldridge Avatar answered Oct 04 '22 00:10

Timothy Baldridge