Lesson 4

Inheritance in C# Classes

Introduction

Hello again! In this part of our C# Class Basics Revision, we delve into inheritance in object-oriented programming (OOP) with C#. Inheritance allows us to share code across classes, thus improving readability and efficiency.

In this lesson, we'll clarify attribute and method inheritance in C# using practical examples. Our lesson's blueprint includes defining inheritance, examining attribute inheritance, exploring method inheritance, and decoding the base keyword in C#. Ready? Let's get started!

Defining Inheritance

Inheritance involves creating a child class that inherits details from a parent class. In C#, we often find scenarios where classes share common attributes or methods, which makes inheritance highly useful.

The : symbol is used to set up inheritance, allowing one class to inherit properties and methods from another class. Here's an example featuring a parent class named Vehicle and a child class named Car:

C#
1// Define the parent class 'Vehicle' 2class Vehicle { 3 // Initialize the Vehicle with color and brand attributes 4 public string Color { get; } 5 public string Brand { get; } 6 7 public Vehicle(string color, string brand) { 8 Color = color; 9 Brand = brand; 10 } 11} 12 13// Define the child class 'Car', inheriting from 'Vehicle' 14class Car : Vehicle { 15 public int Doors { get; } 16 17 public Car(string color, string brand, int doors) : base(color, brand) { 18 Doors = doors; 19 } 20}

In the Car class, the base() constructor inside its constructor calls the Vehicle class's constructor, enabling the inherited properties to be initialized correctly. The : symbol signifies that Car is a subclass of Vehicle.

Inheritance types, such as Single, Multiple, Multilevel, and Hierarchical, in C# cater to different needs. However, our focus in this lesson is primarily on single inheritance, where one parent class feeds one child class.

Attribute Inheritance

Attribute inheritance allows a child class to inherit the attributes of a parent class, with the exception of private fields. Private fields (declared with the private keyword) are not accessible in child classes.

Consider this example featuring a parent class named Artist, and a child class named Musician:

C#
1using System; 2 3public class Artist { 4 public string Name { get; } 5 6 public Artist(string name) { 7 Name = name; 8 } 9} 10 11public class Musician : Artist { 12 public string Instrument { get; } 13 14 public Musician(string name, string instrument) : base(name) { 15 Instrument = instrument; 16 } 17} 18 19public class Program { 20 public static void Main(string[] args) { 21 var john = new Musician("John Lennon", "Guitar"); 22 Console.WriteLine(john.Name); // Output: John Lennon 23 Console.WriteLine(john.Instrument); // Output: Guitar 24 } 25}

However, if the Name attribute in the Artist class were private, it wouldn't be accessible in the Musician class:

C#
1using System; 2 3public class Artist { 4 private string _name; 5 6 public Artist(string name) { 7 _name = name; 8 } 9 10 public string GetName() { 11 return _name; 12 } 13} 14 15public class Musician : Artist { 16 public string Instrument { get; } 17 18 public Musician(string name, string instrument) : base(name) { 19 Instrument = instrument; 20 } 21} 22 23public class Program { 24 public static void Main(string[] args) { 25 var john = new Musician("John Lennon", "Guitar"); 26 Console.WriteLine(john.GetName()); // Output: John Lennon 27 Console.WriteLine(john.Instrument); // Output: Guitar 28 } 29}

The Musician class inherits the _name attribute from the Artist class and also has its own unique attribute, Instrument, but it accesses the _name attribute via a getter method since _name is private.

Method Inheritance

Similar to attributes, method or function inheritance allows a child class to inherit the methods of a parent class.

In the example below, the Car class can invoke the Start method from the Vehicle class:

C#
1using System; 2 3public class Vehicle { 4 public string Brand { get; } 5 6 public Vehicle(string brand) { 7 Brand = brand; 8 } 9 10 public void Start() { 11 Console.WriteLine($"The {Brand} is starting."); 12 } 13} 14 15public class Car : Vehicle { 16 public Car(string brand) : base(brand) { } 17} 18 19public class Program { 20 public static void Main(string[] args) { 21 var myCar = new Car("BMW"); 22 myCar.Start(); // Output: The BMW is starting. 23 } 24}

In the absence of an explicitly defined constructor in the Car class, C# automatically provides a default constructor, which internally calls base() to ensure the parent class's constructor is invoked. This initialization allows the Car class to inherit the Brand attribute from the Vehicle class seamlessly.

Understanding the base Keyword

The base keyword is integral to inheritance for calling parent class methods from a child class, particularly useful in method overriding and initialization. It allows a child class to extend or utilize the functionality of a parent class without directly modifying it.

Method overriding in C# allows a child class to provide a specific implementation of a method that is already defined in its parent class. This is achieved by using the override keyword in the child class and the virtual keyword in the parent class.

For instance, when overriding a method to add or alter its behavior, base enables calling the original method from the parent class to integrate its functionality with new enhancements:

C#
1using System; 2 3public class Vehicle { 4 public virtual string Start() { 5 return "Vehicle is starting..."; 6 } 7} 8 9public class Car : Vehicle { 10 public override string Start() { 11 return base.Start() + " Beep! Beep!"; 12 } 13} 14 15public class Program { 16 public static void Main(string[] args) { 17 var myCar = new Car(); 18 Console.WriteLine(myCar.Start()); // Output: Vehicle is starting... Beep! Beep! 19 } 20}

Similarly, during initialization, base calls the constructor method of the parent class, making sure that the child class is properly initialized, allowing the child class to add its specific attributes seamlessly:

C#
1using System; 2 3public class ParentClass { 4 public string Value { get; } 5 6 public ParentClass(string value) { 7 Value = value; 8 } 9} 10 11public class ChildClass : ParentClass { 12 public string AdditionalValue { get; } 13 14 public ChildClass(string value, string additionalValue) : base(value) { 15 AdditionalValue = additionalValue; 16 } 17} 18 19public class Program { 20 public static void Main(string[] args) { 21 var childClass = new ChildClass("value", "additional_value"); 22 Console.WriteLine(childClass.Value); // Output: value 23 Console.WriteLine(childClass.AdditionalValue); // Output: additional_value 24 } 25}

In these ways, base facilitates a coherent and modular approach to inheritance by allowing child classes to build upon or adapt the functionality of their parent classes efficiently and cleanly.

Lesson Summary

We've successfully explored attribute and method inheritance in C# and practiced using several examples. Mastering these concepts in real-life programming can enhance both efficiency and readability. Remember, practice is essential for proficiency!

On that note, are you ready for some practice exercises? They will solidify your understanding and prepare you for more complex programming tasks. Programming is all about experimenting, learning, and problem-solving. Enjoy the journey!

Enjoy this lesson? Now it's time to practice with Cosmo!

Practice is how you turn knowledge into actual skills.