Inheritance and Derived Classes (C# vs Java)

You can extend the functionality of an existing class by creating a new class that derives from the existing class. The derived class inherits the properties of the base class, and you can add or override methods and properties as required.

In C#, both inheritance and interface implementation are defined by the : operator, equivalent to extends and implements in Java. The base class should always be leftmost in the class declaration.

Like Java, C# does not support multiple inheritance, meaning that classes cannot inherit from more than one class. You can, however, use interfaces for that purpose in the same way as in Java.

The following code defines a class called CoOrds with two private member variables x and y representing the position of the point. These variables are accessed through properties called X and Y respectively:

public class CoOrds
{
    private int x, y;

    public CoOrds()  // constructor
    {
        x = 0;
        y = 0;
    }

    public int X
    {
        get { return x; }
        set { x = value; }
    }

    public int Y
    {
        get { return y; }
        set { y = value; }
    }
}

You derive a new class, called ColorCoOrds, from the CoOrds class, as follows:

public class ColorCoOrds : CoOrds

ColorCoOrds then inherits all the fields and methods of the base class, to which you can add new ones to provide extra features in the derived class according to our needs. In this example, you add a private member and accessors to add color to the class:

public class ColorCoOrds : CoOrds
{
    private System.Drawing.Color screenColor;


    public ColorCoOrds()  // constructor
    {
        screenColor = System.Drawing.Color.Red;
    }

    public System.Drawing.Color ScreenColor
    {
        get { return screenColor; }
        set { screenColor = value; }
    }
}

The constructor of the derived class implicitly calls the constructor for the base class, or the superclass in Java terminology. In inheritance, all base class constructors are called before the derived class's constructors in the order that the classes appear in the class hierarchy.

Typecasting to a Base Class

As in Java, you cannot use a reference to a base class to access the members and methods of a derived class even if the base class reference may contain a valid reference to an object of the derived type.

You can reference a derived class with a reference to the derived type implicitly:

ColorCoOrds color1 = new ColorCoOrds();
CoOrds coords1 = color1;

In this code, the base class reference, coords1, contains a copy of the color1 reference.

The base Keyword

You can access base class members in a subclass even when those base members are overridden in the superclass using the base keyword. For instance, you can create a derived class which contains a method with the same signature as in the base class. If you prefaced that method with the new keyword, you indicate that this is an all-new method belonging to the derived class. You could still provide a method for accessing the original method in the base class with the base keyword.

For instance, say your base CoOrds class had a method called Invert(), which swaps the x and y coordinates. You could provide a substitute for this method in your derived ColorCoOrds class with code like this:

public new void Invert()
{
    int temp = X;
    X = Y;
    Y = temp;
    screenColor = System.Drawing.Color.Gray;
}

As you can see, this method swaps x and y, and then sets the coordinates' color to gray. You could provide access to the base implementation for this method by creating another method in ColorCoOrds, such as this one:

public void BaseInvert()
{
    base.Invert();
}

You then invoke the base method on a ColorCoOrds object by calling the BaseInvert() method.

ColorCoOrds color1 = new ColorCoOrds();
color1.BaseInvert();

Remember that you would get the same effect if you assigned a reference to the base class to an instance of ColorCoOrds, and then accessed its methods:

CoOrds coords1 = color1;
coords1.Invert();

Selecting Constructors

Base class objects are always constructed before any deriving class. Thus the constructor for the base class is executed before the constructor of the derived class. If the base class has more than one constructor, the derived class can decide the constructor to be called. For example, you could modify your CoOrds class to add a second constructor, as follows:

public class CoOrds
{
    private int x, y;

    public CoOrds()
    {
        x = 0;
        y = 0;
    }

    public CoOrds(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

You could then change the ColorCoOrds class to use a particular one of the available constructors using the base keyword:

public class ColorCoOrds : CoOrds
{
    public System.Drawing.Color color;

    public ColorCoOrds() : base ()
    {
        color = System.Drawing.Color.Red;
    }

    public ColorCoOrds(int x, int y) : base (x, y)
    {
        color = System.Drawing.Color.Red;
    }
}

In Java, this functionality is implemented using the super keyword.

Method Overriding

A derived class may override the method of a base class by providing a new implementation for the declared method. An important distinction between Java and C# is that by default, Java methods are marked as virtual, while in C#, methods must be explicitly marked as virtual using the virtual modifier. Property accessors, as well as methods, can be overridden in much the same way.

Virtual Methods

A method that is to be overridden in a derived class is declared with the virtual modifier. In a derived class, the overridden method is declared using the override modifier.

The override modifier denotes a method or a property of a derived class that replaces one with the same name and signature in the base class. The base method, which is to be overridden, must be declared as virtual, abstract, or override: it is not possible to override a non-virtual or static method in this way. Both the overridden and the overriding method or property must have the same access-level modifiers.

The following example shows a virtual method called StepUp that is overridden in a derived class with the override modifier:

public class CountClass 
{
    public int count; 

    public CountClass(int startValue)  // constructor
    {
        count = startValue;
    }

    public virtual int StepUp()
    {
        return ++count;
    }
}

class Count100Class : CountClass 
{
    public Count100Class(int x) : base(x)  // constructor 
    {
    }

    public override int StepUp()
    {
        return ((base.count) + 100);
    }
}

class TestCounters
{
    static void Main()
    {
        CountClass counter1 = new CountClass(1);
        CountClass counter100 = new Count100Class(1);

        System.Console.WriteLine("Count in base class = {0}", counter1.StepUp());
        System.Console.WriteLine("Count in derived class = {0}", counter100.StepUp());
    } 
}

When you run this code, you see that the derived class's constructor uses the method body given in the base class, letting you initialize the count member without duplicating that code. Here is the output:

Count in base class = 2

Count in derived class = 101

Abstract Classes

An abstract class declares one or more methods or properties as abstract. Such methods do not have an implementation provided in the class that declares them, although an abstract class can also contain non-abstract methods, that is, methods for which an implementation has been provided. An abstract class cannot be instantiated directly, but only as a derived class. Such derived classes must provide implementations for all abstract methods and properties, using the override keyword, unless the derived member is itself declared abstract.

The following example declares an abstract Employee class. You also create a derived class called Manager that provides an implementation of the abstract Show() method defined in the Employee class:

public abstract class Employee 
{ 
    protected string name;

    public Employee(string name)  // constructor
    { 
        this.name = name;
    }

    public abstract void Show();  // abstract show method
}

public class Manager: Employee
{ 
    public Manager(string name) : base(name) {}  // constructor 

    public override void Show()  //override the abstract show method
    {
        System.Console.WriteLine("Name : " + name);
    }
}

class TestEmployeeAndManager
{ 
    static void Main()
    { 
        // Create an instance of Manager and assign it to a Manager reference:
        Manager m1 = new Manager("H. Ackerman");
        m1.Show();

        // Create an instance of Manager and assign it to an Employee reference:
        Employee ee1 = new Manager("M. Knott");
        ee1.Show();  //call the show method of the Manager class
    } 
}

This code invokes the implementation of Show() provided by the Manager class, and prints the employee names on the screen. Here is the output:

Name : H. Ackerman

Name : M. Knott

Interfaces

An interface is a sort of skeleton class, containing method signatures but no method implementations. In this way, interfaces are like abstract classes that contain only abstract methods. C# interfaces are very similar to Java interfaces, and work in very much the same way.

All the members of an interface are public by definition, and an interface cannot contain constants, fields (private data members), constructors, destructors, or any type of static member. The compiler will generate an error if any modifier is specified for the members of an interface.

You can derive classes from an interface in order to implement that interface. Such derived classes must provide implementations for all the interface's methods unless the derived class is declared abstract.

An interface is declared identically to Java. In an interface definition, a property indicates only its type, and whether it is read-only, write-only, or read/write by get and set keywords alone. The interface below declares one read-only property:

public interface ICDPlayer
{ 
    void Play();  // method signature 
    void Stop();  // method signature 

    int FastForward(float numberOfSeconds);

    int CurrentTrack  // read-only property
    {
        get;
    } 
}

A class can inherit from this interface using a colon in place of Java's implements keyword. The implementing class must provide definitions for all methods, and any required property accessors, as follows:

public class CDPlayer : ICDPlayer
{
    private int currentTrack = 0;

    // implement methods defined in the interface 
    public void Play()
    {
        // code to start CD...
    }

    public void Stop()
    {
        // code to stop CD...
    }

    public int FastForward(float numberOfSeconds)
    {
        // code to fast forward CD using numberOfSeconds... 

        return 0;  //return success code
    }

    public int CurrentTrack  // read-only property
    { 
        get 
        { 
            return currentTrack; 
        } 
    }

    // Add additional methods if required...
}

Implementing Multiple Interfaces

A class can implement multiple interfaces using the following syntax:

public class CDAndDVDComboPlayer : ICDPlayer, IDVDPlayer

If a class implements more than one interface where there is ambiguity in the names of members, it is resolved using the full qualifier for the property or method name. In other words, the derived class can resolve the conflict by using the fully qualified name for the method to indicate to which interface it belongs, as in ICDPlayer.Play().

See Also

Concepts

C# Programming Guide

Reference

Inheritance (C# Programming Guide)

Other Resources

The C# Programming Language for Java Developers