#335 – Accessing a Derived Class Using a Base Class Variable

You can use a variable whose type is a base class to reference instances of a derived class.

However, using the variable whose type is the base class, you can use it to access only members of the base class and not members of the derived class.

In the example below, we have two instances of the Terrier class, which derives from Dog.  One instance is referenced by a variable of type Terrier.  Using this variable, you have access to all members of the Terrier class.  On the other hand, the variable whose type is Dog can only reference members of the Dog class, even though the reference points to an instance of a Terrier.

            Terrier bubba = new Terrier("Bubba", 2, "Happy");
            bubba.Growl();    // Can call Terrier.Growl

            Dog jack = new Terrier("Jack", 17, "Surly");
            jack.Growl();     // ERROR: Can't call Growl method

#334 – A Base Class Variable Can Refer to Instances of Derived Classes

A variable whose type is a particular class can refer to instances of that class or it can refer to instances of any derived classes.

Assume that we have a Dog class (base class) and a Terrier class (derived class) that inherits from Dog.  A variable of type Dog can then refer to either a Dog or a Terrier.

Dog kirby = new Dog("Kirby", 15);

// Dog variable can point to Terrier
Dog jack = new Terrier("Jack", 17, "Surly");

// Terrier variable can also point to Terrier
Terrier bubba = new Terrier("Bubba", 2, "Happy");

Notice that even though the variable jack is of type Dog, it still points to an instance of a Terrier.

#333 – Class Inheritance Leads to a Hierarchy of Classes

Defining a new class, you can specify that it inherits data and behavior from any other existing class, or you can allow the new class to implicitly inherit from System.Object.  Because the new class can inherit from a class that itself inherits from another class, you end up defining a hierarchy of parent / child (base class / derived class) relationships.

Consider the picture shown below.  The user has defined a Dog class, which implicitly inherits from the predefined System.Object class.  They also define the Hound and Terrier classes, both of which inherit from Dog, as well as the FoxTerrier class, which inherits from Terrier.

333-005

A class inherits data and methods not only from its immediate parent, but also from other classes higher up in the inheritance chain.  For example, the FoxTerrier class inherits data and methods from Terrier, but also from the Dog class, as well as the System.Object class.

#332 – Every Class Inherits from Exactly One Class

Every class that you define in C# will inherit from exactly one class.

You can explicitly define a base class that the new class inherits from.

    public class Terrier : Dog

Or you can avoid specifying a base class when you define a new class.

    public class Terrier

If you don’t specify a base class, the new class will be automatically derived from System.Object.  You can see this by causing Intellisense to pop up for an instance of the class.  You see the class members of System.Object–e.g. Equals, GetHashCode, GetType, etc.

#331 – Calling a Base Class Constructor Implicitly vs. Explicitly

In a derived class, you can call a constructor in the base class explicitly using the base keyword.

    public class Terrier : Dog
    {
        public string Attitude { get; set; }

        public Terrier(string name, int age, string attitude)
            : base(name, age)
        {
            Attitude = attitude;
        }

If you don’t explicitly call a base class constructor, the default (parameterless) constructor is called implicitly.

        public Terrier(string name, int age, string attitude)
        {
            // Default Dog constructor has already been called
            //   at this point.
            Name = name;
            Age = age;
            Attitude = attitude;
        }

If you do omit the base keyword, the base class must define a default (parameterless) constructor.  If it doesn’t, the compiler will complain that the base class doesn’t have a constructor that takes 0 arguments.

#330 – Derived Classes Do Not Inherit Constructors

A derived class inherits all of the members of a base class except for its constructors.

You must define a constructor in a derived class unless the base class has defined a default (parameterless) constructor.  If you don’t define a constructor in the derived class, the default constructor in the base class is called implicitly.

When you define a constructor in a derived class, you can call a constructor in the base class by using the base keyword.

Here’s an example:

    public class Dog
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }
    }

    public class Terrier : Dog
    {
        public string Attitude { get; set; }

        // Call the Name/Age constructor in the base class
        public Terrier(string name, int age, string attitude)
            : base(name, age)
        {
            Attitude = attitude;
        }
    }

#329 – A Class Can Inherit Data and Behavior from Another Class

A class can inherit data and behavior from another class.  The new class (“derived class”) automatically includes all members of the class that it inherits from (“base class”) and can also define new members.

To inherit from another class, add a ‘:’ (colon) and the name of the base class in the definition of the derived class.

    public class Dog
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public void Bark()
        {
            Console.WriteLine("{0} says woof", Name);
        }
    }

    public class Terrier : Dog
    {
        public string Attitude { get; set; }

        public void Growl()
        {
            Console.WriteLine("{0} says Grrrr", Name);
        }
    }

We can now create instances of both the Dog and the Terrier classes:

            Dog lassie = new Dog();
            lassie.Name = "Lassie";
            lassie.Age = 71;
            lassie.Bark();

            Terrier jack = new Terrier();
            jack.Name = "Jack";
            jack.Age = 17;
            jack.Attitude = "Aloof";
            jack.Bark();
            jack.Growl();