#677 – Method Marked with new Modifier Cannot Be Overridden

You can use the new modifier on a method to indicate that the method should hide a method of the same name in a base class.  In other words, the method does not behave polymorphically.

If you’ve marked a method as new in a class, that method is not virtual and can not be overridden in a derived class.

In the example below, the Dog class marks Bark as virtual, indicating that it can be overridden.  The Terrier class marks Bark as new, indicating that it does not override Dog.Bark–and that it cannot be overridden.  JRT can therefore not override Bark.

    public class Dog
    {
        public virtual void Bark()
        {
            Console.WriteLine("  Dog.Bark");
        }
    }

    public class Terrier : Dog
    {
        public new void Bark()
        {
            Console.WriteLine("  Terrier is barking");
        }
    }

    public class JRT : Terrier
    {
        public new void Bark()
        {
            Console.WriteLine("  JRT is barking");
        }
    }

Advertisements

#676 – An Overridden Method Can Itself Be Overridden

To get polymorphic behavior for a method in a derived class, you need to mark the method in the base class as virtual and the method in the derived class as override.  This allows the method in the derived class to be called at runtime, even when referenced by a variable whose type is the base class.

    public class Dog
    {
        public virtual void Bark()
        {
            Console.WriteLine("  Dog.Bark");
        }
    }

    public class Terrier : Dog
    {
        public override void Bark()
        {
            Console.WriteLine("  Terrier is barking");
        }
    }

The Bark method in Terrier overrides the version in Dog.  But the override method also indicates that the Bark method can itself be overridden in a class that derives from Terrier.

    public class JRT : Terrier
    {
        public override void Bark()
        {
            Console.WriteLine("  JRT is barking");
        }
    }

The Bark method is now polymorphic across all three types.

#675 – Polymorphic Behavior Requires virtual / override Combination

Recall that polymorphism means that the type of an object at run-time is used to decide what method to call, rather than the static type of the variable that references that object.

In C#, a method behaves polymorphically if and only if the method in the base class is defined as virtual and the method in the derived class is defined as override.  

For example, if Terrier inherits from Dog, we can declare a Dog.Bark method as virtual and a Terrier.Bark method as override.  We then get polymorphic behavior:

Terrier t = new Terrier("Jack");
Dog d = t;

// Polymorphic behavior =
//   Terrier's implementation of Bark is called,
//   because type of object referenced by d is
//   determined at runtime.
d.Bark();

#671 – A Base Class Constructor Can Call a Virtual Method

If a base class constructor calls a virtual method that is overridden in a derived class, the version of the method in the derived class is the one that will get called.

For example, assume that we have a Dog class that defines a virtual Bark method and a Terrier subclass that overrides the Bark method.

    public class Dog
    {
        public Dog()
        {
            Console.WriteLine("Dog constructor");
            Bark();
        }

        public virtual void Bark()
        {
            Console.WriteLine("Woof");
        }
    }

    public class Terrier : Dog
    {
        public Terrier()
            : base()
        {
            Console.WriteLine("Terrier constructor");
        }

        public override void Bark()
        {
            Console.WriteLine("Terrier barking!");
        }
    }

Assume you create an instance of a Terrier.

            Terrier t = new Terrier();

The Terrier constructor calls the Dog constructor, which invokes the Bark method.  But it’s the Bark method in Terrier that is called, rather than the Bark method in Dog.

#616 – Base Class Needs to Know If Polymorphism Is Desired

Let’s say that you design a Dog class that contains a Bark method and that you don’t do anything special to design for inheritance.

    public class Dog
    {
        public void Bark()
        {
            Console.WriteLine("Woof");
        }
    }

Now let’s say that you define several classes that inherit from Dog and provide their own implementation for the Bark method.  Because Dog.Bark was not marked as virtual, they must use the new keyword.

    public class Terrier : Dog
    {
        public new void Bark()
        {
            Console.WriteLine("Terrier says Grrrr");
        }
    }

But now you do not get polymorphic behavior when treating instances of Terrier as instances of Dog.

        static void Main()
        {
            Terrier t = new Terrier();
            t.Bark();  // Terrier.Bark
            SomeoneBark(t);
        }

        static void SomeoneBark(Dog d)
        {
            d.Bark();  // Dog.Bark always invoked--no polymorphism
        }

To achieve polymorphism, you must design for it in the base class by marking a method as virtual.

#360 – Property Modifiers Required for Polymorphic Behavior

There are three combinations of modifiers that make sense, in determining whether properties in a class are virtual or non-virtual.

Typical combinations of modifiers for base class / derived class (assuming that the property’s name and type are the same in both the base and derived class):

  • (no modifier) / new – Both properties are non-virtual, derived class property hides the base class property
  • virtual / override – Both properties are virtual and support polymorphic behavior
  • virtual / new – Base class property is virtual, derived class property is non-virtual, derived class property hides the base class property

There are two other combinations that are allowed, but result in a compiler warning indicating that you should use new in the derived class to be explicit:

  • (no modifier) / (no modifier) – is equivalent to: (no modifier) / new
  • virtual / (no modifier) – is equivalent to: virtual / new

#359 – The Difference Between Virtual and Non-Virtual Properties

In C#, virtual properties support polymorphism, by using a combination of the virtual and override keywords.  With the virtual keyword on the property in the base class and the override keyword on the property in the derived class, both properties are said to be virtual.

Properties that don’t have either the virtual or override keywords, or that have the new keyword, are said to be non-virtual.

When you read or write a virtual property through an object reference, the run-time type of the object is used to determine which implementation of the property to use.

When you read or write a non-virtual property through an object reference, the compile-time type of the object is used to determine which implementation of the property to use.