Click here to Skip to main content
15,867,750 members
Articles / Programming Languages / C#
Article

Object-Oriented Programming in C# .NET - Part 5

Rate me:
Please Sign up or sign in to vote.
4.00/5 (7 votes)
7 Jul 2011CPOL5 min read 44.3K   28   11
A discussion of virtual and override members, overriding operators, interfaces and nested types in C#

Introduction

In the last part of Object-Oriented Programming, we will go through the following:

  • Virtual and Override Members
  • Overriding Operators
  • Interfaces
  • Nested Types

What are Virtual and Override Members?

Virtual and Override members (methods, properties) are another kind of polymorphism. When you derive from a base class, that base class may have some virtual members and allow you to override them. That is, change their implementation so that when called by an object of your class does a different thing. The best way of understanding it is through an example. Suppose you derive from a base class named Car. This Car class possesses a method named Accelerate:

C#
class Car
{
    private int speed;
    public void Accelerate()
    {
        speed += 10;
    }
}

When you instantiate an object of type car and call the Accelerate method, the value stored in speed will increase by 10. Now, you want to create a much faster Car class that when its Accelerate method is called, its speed increases by 30. And, of course, this new car derives from the base car class:

C#
class MuchFasterCar:Car
{
    private int speed;
    public void Accelerate()
    {
        speed += 30;
        Console.WriteLine ( speed );
    }
}

If you build the solution, you will get a warning. The solution to this warning is that the Accelerate method in Car class should be declared as virtual which allows you to override it within the MuchFasterClass:

C#
class Car
{
    private int speed;
    public virtual  void Accelerate()
    {
        speed += 10;
        Console.WriteLine (speed );
    }
}

class MuchFasterCar:Car
{
    private int speed;
    public override  void Accelerate()
    {
        speed += 30;
        Console.WriteLine ( speed );
    }
}

This means that the Car and the MuchFasterCar have their own specific implementation for Accelerate method. Your don’t have to override each single method, but if you don’t you will get a warning:

C#
class Car
{
    private int speed;
    public virtual  void Accelerate()
    {
        speed += 10;
        Console.WriteLine (speed );
    }
}

class MuchFasterCar:Car
{
    private int speed;
    public void Accelerate()
    {
        speed += 30;
        Console.WriteLine ( speed );
    }
}

You also have the option of marking the method as new which hides the base’s virtual method without generating any warnings:

C#
class Car
{
    private int speed;
    public virtual  void Accelerate()
    {
        speed += 10;
        Console.WriteLine (speed );
    }
}

class MuchFasterCar:Car
{
    private int speed;
    public new void Accelerate()
    {
        speed += 30;
        Console.WriteLine ( speed );
    }
}

Overriding is not limited to methods. It also happens on properties:

C#
class Car
{
    private int speed;
      public virtual  int Speed
    {
        get { return speed; }
        set { speed = value; }
    }

    public virtual  void Accelerate()
    {
        speed += 10;
        Console.WriteLine (Speed );
    }
}

class MuchFasterCar:Car
{
    private int muchFasterSpeed;
    public override int Speed
    {
        get
        {
            return muchFasterSpeed;
        }
        set
        {
            muchFasterSpeed = value;
        }
    }
    public new void Accelerate()
    {
        muchFasterSpeed += 30;
        Console.WriteLine ( Speed  );
    }
}

In the above example, the Speed properties which is declared as virtual in Car class is overridden in MuchFasterCar class.

What are Overriding Operators?

Have you ever thought of the way the + operator works. When used on two integers, it simply works like an Add method in a Math class.

C#
class Program
{
    static void Main(string[] args)
    {
        int a = 3 + 2;
        Console.WriteLine (a);
        Console.ReadKey ();
    }
}

When used on strings, it concats them (appends the last string to the end of the one before last):

C#
class Program
{
    static void Main(string[] args)
    {
        string s = "Hello " + "World!";
        Console.WriteLine (s);
        Console.ReadKey ();
    }
}

So, as you see, the + operator does different things based on the type it’s working on. What if you want to make the + operator do yet another different thing on objects of your class. Suppose you have a Point class which has an X and Y coordinates. You want to override the + sign on this Point class so that when it’s applied to objects of type Point, it simply adds the Xs and Ys and return a new Point object:

C#
class Point
{
    private int x;

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

    public int Y
    {
        get { return y; }
        set { y = value; }
    }
    public Point(int xVal,int yVal)
    {
        X = xVal;
        Y = yVal;
    }

    public static Point operator +(Point a,Point b)
    {
        Point result = new Point ( a.X + b.X, a.Y + b.Y );
        return result;
    }
}

Note the signature of the method that overrides the + operator. It’s declared as public and static (always must be), it returns an object of type Point, it has the operator keyword, it specifies the name of the operator that is overriding. Now, look at the following code:

C#
class Program
{
    static void Main(string[] args)
    {
        Point p1 = new Point ( 2, 4 );
        Point p2 = new Point ( 5, 6 );
        Point p3 = p1 + p2;

        Console.WriteLine (p3.X );
        Console.WriteLine (p3.Y );
        Console.ReadKey ();
    }
}

Run the solution and see the results. You can override the *,/,- operators similarly.

What are Interfaces?

Interfaces are like contracts. If your class is to have a certain capability, it must override a certain interface. Another use of interfaces is providing multiple inheritance, which is impossible in C# using class derivation. That means that you can derive from only and only one class but you can implement as many interfaces as you desire. Suppose you want to make an Animal hierarchy. You create a base abstract class named Animal that every class in the hierarchy derives from. The reason to create the Animal class as abstract is that it should not be instantiated (an abstract class cannot be instantiated.). Now some animals are carnivore, some are herbivore, some are reptiles. You cannot make a class, say, Crocodile derive from Animal, Carnivore, Reptile. Instead, you declare everything except the base Animal class as interfaces. Therefore, the Crocodile class is an Animal which implements the Carnivore, Reptile interfaces (which are also like contracts. If the Crocodile is to be thought as a carnivore and a reptile, it must implement a certain, in this case Carnivore and Reptile, interfaces.). I won’t write the codes for all of these classes, but I assure you will get the idea:

C#
abstract class Animal
{
    public abstract void Feed();
    public abstract void Move();
}

interface ICarnivore
{
    void Hunt();
}
interface IHerbivore
{
    void Chew();
}
interface IReptile
{
    void Crawl();
}

class Crocodile:Animal,IReptile,ICarnivore
{

}
class Lion:Animal,ICarnivore
{

}

Every single member that is within an interface must be implemented by the class which uses it. For example, the code of the Lion class would be as follows:

C#
class Lion:Animal,ICarnivore
{
    public override void Feed()
    {
        Console.WriteLine ("Feeding");
    }
    public override void Move()
    {
        Console.WriteLine ("Moving");
    }
    public void Hunt()
    {
        Console.WriteLine ( "Hunting" );
    }
}

There are lots of built-in interfaces which you can use to give your class additional functionality. For instance, if you want your class to be sortable (if you have an array containing objects of your class and you want to sort that array), you must add IComparable interface to your class and implement its CompareTo method.

One interesting thing about interfaces is that you can assign an object of a particular type to an interface provided that class implements that interface as you can do the same with an abstract class:

C#
class Program
{
    static void Main(string[] args)
    {
        ICarnivore l = new Lion ();
        Animal a = new Lion ();
    }
}

What are Nested Types?

You can declare a class within another class. The inner class in called the nested class and the outer class is called the nesting class. This is done when the nested class is meaningless out of the scope of the nesting class. In UML, this is called composition relationship. Suppose we want to declare a class named Human. Humans have hearts. Now, Heart is the other class we want to create. However, let’s assume that a heart is meaningless if there is no human. Therefore, we create the Heart class within our Human class:

C#
public class Human
{
    int age;
    public int Age
    {
        get { return age; }
        set { age = value; }
    }
    public class Heart
    {
        Human owner;

        public Human Owner
        {
            get { return owner; }
            set { owner = value; }
        }
        public Heart(Human ownerVal)
        {
            Owner = ownerVal;
        }
        bool isHealthy;

        public bool IsHealthy
        {
            get { return isHealthy; }
            set { isHealthy = value; }
        }
    }
}

Now, we can use these classes as follows:

C#
class Program
{
    static void Main(string[] args)
    {
        Human human = new Human ();
        human.Age = 12;
        Human.Heart heart = new Human.Heart ( human );
        Console.WriteLine (heart.Owner.Age );
        Console.ReadKey ();
    }
}

That’s all for the last part of this article. Thank you for spending time studying this series of articles. Hope you have learnt helpful and interesting things.

History

  • 5th July, 2011: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Iran (Islamic Republic of) Iran (Islamic Republic of)
I'm a software engineer specialized in .NET framework. I've developed applications in such technologies as Console Applications, Windows Forms, WPF, Web Forms, MVC, Silverlight and Xamarin Forms. I also create and publish my multimedia courses at provid.ir and softdevwithmorteza.wordpress.com.
Some of my courses inclue Design Patterns in C#, OOP Principles, SOLID Principles, High Quality Coding Principles, Anti-patterns, Refactoring, TDD, DDD, .NET Core and so on.

Comments and Discussions

 
QuestionGood Basic Article Pin
jbprinsloo14-Feb-15 0:02
jbprinsloo14-Feb-15 0:02 
GeneralMy vote of 4 Pin
ArunKS78329-Nov-12 0:59
ArunKS78329-Nov-12 0:59 
QuestionGood Artilcle Series on OOPS Pin
kansee7-Aug-11 2:16
kansee7-Aug-11 2:16 
GeneralMy vote of 3 Pin
Abolfazl Khusniddinov12-Jul-11 1:18
Abolfazl Khusniddinov12-Jul-11 1:18 
Questiondecent Pin
BillW338-Jul-11 3:27
professionalBillW338-Jul-11 3:27 
QuestionI think you should explain in more details... Pin
Paulo Zemek7-Jul-11 10:46
mvaPaulo Zemek7-Jul-11 10:46 
AnswerRe: I think you should explain in more details... Pin
bob32697-Jul-11 15:54
bob32697-Jul-11 15:54 
GeneralRe: I think you should explain in more details... Pin
Ravi Thakur7-Jul-11 18:12
Ravi Thakur7-Jul-11 18:12 
GeneralRe: I think you should explain in more details... Pin
User 16732527-Jul-11 18:24
User 16732527-Jul-11 18:24 
GeneralRe: I think you should explain in more details... Pin
Paulo Zemek8-Jul-11 2:58
mvaPaulo Zemek8-Jul-11 2:58 
GeneralRe: I think you should explain in more details... [modified] Pin
Riz Thon11-Jul-11 14:51
Riz Thon11-Jul-11 14:51 
Indeed, I feel like the articles are more a list of all the things that are possible than an explanation on when to use what. If a beginner reads that, he might be tempted to use "new" all the time because it's faster than writing "virtual" and then "override"...

What's the difference between field and property? What is the goal of a finalizer (or what should you do in a finalizer)? What about the IDisposable interface? What is the point of polymorphism? (for me it's not really the fact that a method has several signatures, it's more that you can use an object without knowing its exact implementation). When should you override operators instead of creating methods? (eg should you be able to add cars?)

So basically, instead of saying "you can do this, you can do that", I feel you should say "you should do this in this case, that in that case". No need to explain everything thouroughly as it's a beginner article, but you can give links to good resources if someone wants to know more about a concept.

modified on Monday, July 11, 2011 9:02 PM

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.