#357 – Property in Derived Class Hides Base Class Property by Default

If you define a property in a derived class with the same name and type as a property in the base class, the new property hides the base class property by default.  This is true even if you don’t use the new keyword to explicitly indicate that you intend to hide the property in the base class.

If we have a Dog.Temperament property, the following two code snippets are functionally equivalent.

    public class Terrier : Dog
    {
        public new string Temperament
        {
            get
            {
                return string.Format("Terrier {0} is {1}", Name, temperament);
            }
        }

 

    public class Terrier : Dog
    {
        // No new keyword, but we're still hiding base class property
        public string Temperament
        {
            get
            {
                return string.Format("Terrier {0} is {1}", Name, temperament);
            }
        }

Without the new keyword, the compiler warns you that you’re hiding the base class property and recommends using the new keyword.

Advertisement

#356 – Hidden Base Class Property Is Used Based on Declared Type of Object

When you use the new modifier to hide a base class property, its property accessors will still be called by objects whose type is the base class.  Objects whose type is the derived class will use the new property in the derived class.

            Dog kirby = new Dog("Kirby", 15);
            kirby.Temperament = "EAGER";
            Console.WriteLine(kirby.Temperament);  // Kirby is eager

            Terrier jack = new Terrier("Jack", 15);
            jack.Temperament = "CraZY";
            Console.WriteLine(jack.Temperament);  // Terrier Jack is CRAZY

We could also use a variable of type Dog (the base class) to refer to an instance of a Terrier (the derived class).  If we then reference the Temperament property using this base class variable, the Temperament property in the base class is used, even though we’re working with an instance of the derived class.

            Dog kirby = new Dog("Kirby", 15);
            kirby.Temperament = "EAGER";      // Uses Dog.Temperament

            Dog jack = new Terrier("Jack", 15);
            jack.Temperament = "CraZY";       // Also uses Dog.Temperament

#355 – Use the new Keyword to Replace a Property in a Base Class

A derived class inherits data and behavior from its parent class.

There are times when you might want to replace property accessors in a base class with new accessors in the derived class, using the same property name.  You can do this using the new keyword.

Assume a Dog class has a Temperament property:

        protected string temperament;
        public string Temperament
        {
            get
            {
                return string.Format("{0} is {1}", Name, temperament);
            }

            set
            {
                temperament = value.ToLower();
            }
        }

You can provide a new version of this property in a class that derives from Dog, using the new keyword.  This new property hides the property in the base class.

        public new string Temperament
        {
            get
            {
                return string.Format("Terrier {0} is {1}", Name, temperament);
            }

            set
            {
                temperament = value.ToUpper();
            }
        }

The get/set accessors used will now depend on the type of the object.

#354 – Correct Overloaded Method Is Automatically Called

When you have several overloaded methods in a class, the compiler will call the correct method, based on the type of the arguments passed to the method.

When you overload a method, you define several methods in a class with the same name, but different parameters.

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

        // Specific bark
        public void Bark(string barkSound)
        {
            Console.WriteLine(barkSound);
        }

        // Repeated barking
        public void Bark(int numBarks)
        {
            for (int i = 1; i <= numBarks; i++)
                Console.WriteLine("Woof #{0}", i);
        }
    }

The compiler will automatically figure out which method to call, based on the arguments that you pass in.

            Dog jack = new Dog("Jack", 15);

            jack.Bark();           // General bark
            jack.Bark(5);          // Repeated barking
            jack.Bark("Rowwwwf");  // Specific bark

#353 – Why You Might Define an Abstract Class

An abstract class cannot be instantiated and is meant to serve as a base class for other classes.  It might contain implementations for its methods, which derived classes would inherit.  It might also contain one or more abstract methods, with no implementation, which must be overridden in the derived classes.

You’d typically use an abstract class when it would only make sense to instantiate the derived classes and when the base class just serves as a blueprint for the derived classes and to possibly include the implementation of some methods.

For example, you might have a Person class and Man and Woman classes that inherit from Person.  You can imagine only ever creating instances of Man and Woman and never of a generic Person–everyone is either a man or a woman.  You can imagine methods implemented in Person that are common to both men and women, like Sing.

#352 – You Can’t Instantiate an Abstract Class

An abstract class, defined with the abstract keyword, is one that is not meant to be instantiated itself, but serve as a base class for other classes.  A class must be abstract if it contains any abstract methods.

Since an abstract method does not contain an implementation, it doesn’t make sense to instantiate the class containing the abstract method.

You can, however, have non-abstract methods in an abstract class.  Derived classes will inherit the implementation of these methods and could then make use of them.

#351 – An Abstract Method Has No Implementation

An abstract method is a special kind of virtual method, defined in a base class, which has no implementation of its own.  A derived class must define every abstract method and provide an implementation, using the override keyword.

    public abstract class Dog
    {
        // Abstract method has no implementation
        public abstract void Bark();
    }

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

The class in which the abstract method is defined must be defined as an abstract class, using the abstract keyword.

A derived class may not hide the abstract method in the base class, using the new keyword.  It must implement the inherited abstract method and the new method must be a virtual method, defined using the override keyword.

#350 – Method Modifiers Required for Polymorphic Behavior

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

Typical combinations of modifiers for base class / derived class (assuming that method signature is the same in both the base and derived class):

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

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) – effectively (no modifier) / new
  • virtual / (no modifier) – effectively virtual / new

#349 – The Difference Between Virtual and Non-Virtual Methods

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

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

When a virtual method is invoked on an object, the run-time type of the object is used to determine which implementation of the method to use.

When a non-virtual method is invoked on an object, the compile-time type of the object is used to determine which implementation of the method to use.

#348 – Virtual Methods Support Polymorphism

In C#, polymorphism is implemented using virtual methods.  A virtual method has an implementation in the base class that can be overridden in a derived class.  When the method is invoked on an object of the base class’ type, the specific method to be called is determined at run-time based on the type of the underlying object.

A virtual method is defined in the base class using the virtual keyword.

    public class Dog
    {
        public virtual void Bark()
        {
            Console.WriteLine("Generic dog {0} says Woof", Name);
        }
    }

A virtual method is overridden in a derived class using the override keyword.

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

This allows polymorphic behavior when invoking the Bark method.

            Dog jack = new Terrier("Jack", 15);
            jack.Bark();       // Terrier.Bark called, rather than Dog.Bark