Learning to Code — Part 9a: Inheritance & Polymorphism

INHERITANCE

Next up, we go into the Inheritance & Polymorphism section of the SoloLearn app. We definitely talked about polymorphism early on, so I’m hoping to understand that pretty well when we get to it. First, though, we’ll talk about inheritance. The is the ability to define one class based on another class. Apparently, this…

…makes creating and maintaining an application easy.

Mm hmm.

The class whose properties are being inherited by another class is called the base class. The class that is doing the “inheriting” is called the derived class. Their example describes it pretty well:

…base class Animal can be used to derive Cat and Dog classes. The derived class inherits all of the features of the base class, and can have it’s own additional features.

This makes sense so far, and certainly seems like an “efficiency” is that you don’t have to write the same things over and over. So, using their example, the “base” Animal class would look like this:

class Animal {
public int Legs { get; set; }
public int Age { get; set; }
}

Next, we’d like to be able to use the features of that Animal class, and then have some additional features for the “derived” Dog class:

class Dog : Animal {
public Dog() {
Legs = 4;
}
}
public void Bark() {
Console.Write(“Woof”);
}
}

It’s important to note the colon and then the name of the base class (: Animal). Additionally, all public members of the Animal class, become public members of the Dog class (which is why we can access the Legs member in the Dog constructor). Next, we’ll create an instance of the Dog class, access the inherited members from the Animal class, and then also call the Dog class’s own member (specifically, the Bark method):

static void Main(string[] args) {
Dog d = new Dog();
Console.WriteLine(d.Legs);
d.Bark();
}

Here’s what happens when this code is executed:

  • First, a new instance of the Dog class is instantiated, and is called d.
  • Then, we jump to the Dog class, where the constructor method called Dog is immediately (and automatically) run. Within it, a seemingly undeclared variable called Legs is mentioned. But, since the Dog class gets all of the features of the Animal class, a publicly accessible, integer-based variable called Legs is declared.
  • It then gets the value assigned to it from where it was called. That was in the Dog class where, in the constructor method called Dog, the variable Legs was assigned (or set) the value of 4.
  • Jumping back to the Main method, the next line says to print to the screen, the value of the variable called Legs within the instantiation of the Dog class called d. As this is 4, 4 is printed to the screen.
  • Finally, the method called Bark is called within the instantiation of the Dog class called d, which says to print the word “Woof” to the screen.

The app also mentions that the base class can have multiple derived classes. In other words, if there was a class called Cat, it could use the Animal class as well. I also like how they describe inheritance overall:

…the derived class extends the functionality of the base class.

One thing you cannot do, however, is have one class inherit from multiple base classes. Apparently, there’s a way to do it anyway with something called interfaces though, and we’ll learn about that later.

PROTECTED MEMBERS

So far, we’ve only talked about public (members accessible from anywhere outside of the class) and private (members accessible only from within their classes) access modifiers. Protected members are similar to private members, accept that they can also be access from derived classes.

class Person {
protected int Age { get; set; }
protected string Name { get; set; }
}
class Student : Person {
public Student(string nm) {
Name = nm;
}
     public void Speak() {
Console.Write(“Name: “ + Name);
}
}
class Program {
static void Main(string[] args) {
Student s = new Student(“David”);
s.Speak();
}
}

By the way, I decided to write all code in Visual Studio and then just copy/paste it here. I actually write my articles in Microsoft OneNote, and then copy/paste them into Medium (before proofreading). But I really want to get used to coding in Visual Studio all the time, so that’ll be my process.

Anyway, in the code above, the Student class is called, and has the Person class as it’s base class. Therefore, when executed, within the Main method, a new instance of the Student class is instantiated, and called s. Additionally, when created, it sends the string David. Since the Person class is the base class of the (derived) Student class, when the next line of the Main method looks to print the value of the Name property to the screen (with the string Name: coming first), that property is accessible.

Conversely, if we try to access it directly, we’ll get an error:

static void Main(string[] args) {
Student s = new Student(“David”);
s.Name();
}

You can also prevent other classes from inheriting a class (as it’s base) by sealing it with the sealed keyword, like this:

sealed class Animal {
//some code
}
class Dog : Animal {}

DERIVED CLASS CONSTRUCTOR & DESTRUCTOR

Next, the app talks about inheritance. Normally, constructors are called when an instance of a class is instantiated. Within that base class, however, constructors and destructors are NOT inherited like other members are, therefore, constructors for the derived classes need to be defined on their own.

That said, the constructor and destructor of the base class ARE being invoked automatically when an instance of the derived class is instantiated, as in the following:

class Animal {
public Animal() {
Console.WriteLine(“Animal created”);
}
     ~Animal() {
Console.WriteLine(“Animal deleted”);
Console.ReadLine();
}
}
class Dog: Animal {
public Dog() {
Console.WriteLine(“Dog created”);
}
     ~Dog() {
Console.WriteLine(“Dog deleted”);
Console.ReadLine();
}
}
class Program {
static void Main(string[] args) {
Dog d = new Dog();
Console.ReadLine();
}
}

When run, the following happens:

  • First, within the Main method, a new Dog object is instantiated called d.
  • While we then jump to the Dog class, since the Animal class is the base class, it’s constructor is automatically run and, as a result, Animal created is printed to the screen.
  • Then in the (derived) Dog class, the constructor prints Dog created to the screen.
  • With the program running, when I hit the Enter key, the next line of the Dog class is run, the destructor, which prints Dog deleted to the screen.
  • After that, when I tap the Enter key again, since the instance of the Dog class called d has been deleted, the destructor within the Animal class is run, and Animal deleted is printed to the screen.

You’ll also notice that I added Console.ReadLine(); in a few places. This just stops the program from continuing so I can actually see what’s happening. The program does continue when I hit the Enter key.

An important thing that the SoloLearn app mentions is that the constructor of the base class is called first, followed by the constructor of the derived class. Conversely, once the object is destroyed, the destructor of the derived class is invoked first, followed by the destructor of the base class. To make it even clearer, they describe it this way:

The derived class needs it’s base class in order to work, which is why the base class constructor is called first.

POLYMORPHISM

As mentioned way back in Part 2, I ending up watching a video on a YouTube channel called The Coding Train, by Daniel Shiffman, called 4.7: Introduction to Polymorphism — The Nature of Code, and I begun to understand. That said, the word polymorphism means having many forms. In terms of C#, it typically occurs where there are a number of classes that relate to each other through inheritance from a common base class. The SoloLearn app also states the following:

Polymorphism means that a call to a member method will cause a different implementation to be executed depending on the type of object that invokes the method. Simply, polymorphism means that a single method can have a number of different implementations.

While part of polymorphism relates to the derived and base classes, there’s more to it than that, as well see in this section of the app. The example they give is of a program that allows the user to draw different shapes. Obviously, each shape is drawn differently, and we don’t know which shape the user will choose. Polymorphism will allow us to invoke the Draw method within the applicable derived class, by overriding the same method in the base class. These methods must be declared using the keyword virtual (within the base class). So, we can have a base class that looks like this:

class Shape {
public virtual void Draw() {
Console.Write(“Base Draw”);
}
}

That virtual keyword allows that Draw method (within the base class) to be overridden in the a derived class. The app also states:

Virtual methods enable you to work with groups of related objects in a uniform way.

I don’t completely know what that means, but hopefully we’re about to find out. We could have the following derived classes, that have the Shape class above, as their base class:

class Shape {
public virtual void Draw() {
Console.Write(“Base Draw”);
}
}
class Circle : Shape {
public override void Draw() {
//draw a circle…
Console.WriteLine(“Circle Draw”);
}
}
class Rectangle : Shape {
public override void Draw() {
// draw rectangle…
Console.WriteLine(“Rect Draw”);
}
}

It is the override keyword that allows the derived classes to define their own versions of that Draw method. We can now create separate Shape objects from each derived class, and then call their Draw methods, like this:

static void Main(string[] args) {
Shape c = new Circle();
c.Draw();
//Outputs “Circle Draw”
     Shape r = new Rectangle();
r.Draw();
//Outputs “Rect Draw”
}

The thing about the code above that confused me initially was that the instantiation lines say the following…

Shape c = new Circle();
…instead of what we’ve seen before…
Circle c = new Circle();

If we wanted to create a new Circle object, why not call the Circle class, which is derived from the Shape (base) class? In a previous article, I referenced a video created by Tom McCurdy linked to from within the SoloLearn app comments. He created another video called C#: Polymorphism — virtual/override. Around the 7-minute mark, he shows the differences between the two lines of code above. He explains the difference in that…

Shape c = new Circle();

…is creating a new Circle of type Shape and limits the functionality of the Circle class only to the methods within that class that are specifically set with the keyword override. The other line…

Circle c = new Circle();

…does everything the first one does, except that you cannot access any of the other members within the Circle class. I can’t yet envision where this would be useful, but I’d imagine a scenario does exist.

The last section of this lesson does go on to explain it further as well. The app states that…

polymorphism is a way to call the same method for different objects and generate different results based on the object type. This behavior is achieved through virtual methods in the base class.

They also describe Shape c = new Circle(); quite nicely, like this:

…we create objects of the base type, but instantiate them as the derived type.

So, in this case, Shape is the base class, while Circle is the derived class. If we were to create a bunch of objects like this, we could work with them all without knowing the actual derived type of object within, for example, an array.

Another example they give is if we had a game where each player has a different behavior for the Attack method (i.e. Attack would be a virtual method of the base class Player and each derived class would override it).

In other words, when Player 1 attacks Player 2 (i.e. Player 1 calls the Attack method), he punches, but when Player 2 attacks Player 1 (i.e. Player 2 calls the Attack method), he kicks.

So, we’ve now caught up to where I had stopped before starting over with this narrative note-taking methodology. The next section, still within Inheritance & Polymorphism, will be about Abstract Classes…whatever that is.

Anyway, as usual, please let me know if I made any mistakes anywhere, or anything needs additional explanation. Additionally, here’s a link to the previous article, Learning to Code — Part 8b: More on Classes.

Web: BIMuzer.com

Twitter: BIMuzer

LinkedIn: Scott Rosenbloom