Sunday, March 20, 2005

Method and Constructor Calling Order in OOP

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/method_and_constructor_calling_order_in_oop.htm]

I'm starting OOP in my C# class, and one of the issues to explain is the order that methods and constructors are called for inherited objects. People with a vague idea of inheritance know that one object (derived) can inherit another (base), where the derived object can reuse parts of the base. However, the behavior of the objects depends on what order the members are called in. Given a base and derived object, we want to know the code flow if the derived constructor or method is called.

For constructors, the base member is always called first. For methods, the question is really not-applicable because when there is a base and derived method both with the same name, the base member is only called if the the developer explicitly calls it with the base keyword. Let's flush this out.

Constructors

Given the classes:

public class MyBase
{
    public MyBase()
    {
        Console.WriteLine("Mybase()");
    }
}

public class MyDerived : MyBase
{
    public MyDerived()
    {
        Console.WriteLine("MyDerived()");
    }

    public MyDerived(string strName)
    {
        Console.WriteLine("MyDerived(string strName)");
    }

    public MyDerived(string strName, int intId) : this(strName)
    {
        Console.WriteLine("MyDerived(string strName, int intId)");
    }

}

Running MyDerived d = new MyDerived("name",5); will display:

Mybase()
MyDerived(string strName)
MyDerived(string strName, int intId)

As we walk through with the debugger, before executing any code, it will start at the overloaded MyDerived and walk down to the MyBase constructor. Once there, it executes the base constructor and walks back up to the calling point - executing MyDerived(string), and fthen finally MyDerived(string,int).

This makes sense - the base object should be instantiated first because we need to build the individual parts before building the whole.

Methods

Given that base class constructors are executed, many people subconsciously think that in cases where the base and derived methods have the same name, that base methods are executed too. However, this only occurs if the developer explicitly makes it that way, by using the "base" keyword (note that the derived can only call the immediate base, i.e. base.base would return an error):

public new void MyMethod(string strName)
{
    base.MyMethod(strName);
}

If "base.MyMethod(strName)" is omitted, then MyMethod will not be called - not with inheritance, polymorphism, or anything else. As we look at the keywords used in OOP, we see that this makes sense in each individual case:

Base Method: Virtual/AbstractDerived Method: Override/NewResult for calling Derived Method
virtualoverrideOnly current method is called.
abstractoverrideNothing to call (abstract has no implementation)
- (no keyword)newnew keyword hides base, therefore base won't be called by the very nature of what this keyword does.

 

No comments:

Post a Comment