Introduction to Inheritance
Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a new class (called a derived class or child class) to inherit properties and behaviors from an existing class (called a base class or parent class). This promotes code reusability and establishes a hierarchical relationship between classes, often referred to as an "is-a" relationship.
In VB.NET, inheritance enables you to create specialized versions of classes without duplicating code. The derived class automatically gains access to the public and protected members of its base class.
Defining Inheritance
To specify that a class inherits from another class, you use the Inherits
keyword followed by the name of the base class.
' Define a base class
Public Class Shape
Public Property Color As String
Public Overridable Sub Draw()
Console.WriteLine("Drawing a generic shape.")
End Sub
End Class
' Define a derived class that inherits from Shape
Public Class Circle
Inherits Shape
Public Property Radius As Double
' Override the Draw method
Public Overrides Sub Draw()
Console.WriteLine($"Drawing a circle with color {Color} and radius {Radius}.")
End Sub
End Class
Base and Derived Classes
The class from which another class inherits is known as the base class (or parent class, superclass). The class that inherits is known as the derived class (or child class, subclass).
- A derived class can inherit members (fields, properties, methods, events) from its base class.
- By default, derived classes inherit
Public
andProtected
members.Private
members of the base class are not directly accessible in the derived class. - A class can inherit from only one direct base class (single inheritance). However, a class can implement multiple interfaces.
Constructor Chaining
When an object of a derived class is created, the constructor of the derived class is executed. However, before the derived class constructor runs, the constructor of its immediate base class is invoked. This process continues up the inheritance hierarchy until the ultimate base class (Object
in .NET) constructor is called.
You can explicitly specify which base class constructor to call using the MyBase.New()
syntax within the derived class constructor.
Public Class Vehicle
Public Property Manufacturer As String
Public Sub New(manufacturer As String)
Me.Manufacturer = manufacturer
Console.WriteLine("Vehicle constructor called.")
End Sub
End Class
Public Class Car
Inherits Vehicle
Public Property Model As String
Public Sub New(manufacturer As String, model As String)
MyBase.New(manufacturer) ' Call the base class constructor
Me.Model = model
Console.WriteLine("Car constructor called.")
End Sub
End Class
' Example usage:
' Dim myCar As New Car("Toyota", "Camry")
' Output:
' Vehicle constructor called.
' Car constructor called.
Overriding Members
Sometimes, a derived class needs to provide its own specific implementation for a method that is already defined in its base class. This is called overriding.
- The method in the base class must be declared with the
Overridable
keyword. - The method in the derived class must be declared with the
Overrides
keyword. - The signature (name, parameters, and return type) of the overriding method must match the signature of the overridable method in the base class.
Overrides
when you want to change the behavior of a base class method. Use Shadows
(explained next) when you want to hide a base class member with a new member of the same name in the derived class.
Shadowing Members
Shadowing occurs when a derived class declares a member (field, property, method) with the same name as a member in its base class, but the base class member is NotInheritable
or the derived class member is declared with the Shadows
keyword.
Shadowing means the derived class member replaces the base class member for objects of the derived type. The base class member is still accessible using MyBase
.
Public Class Employee
Public Shadowable Property Name As String = "Unknown"
End Class
Public Class Manager
Inherits Employee
' Shadows the Name property from Employee
Public Shadows Property Name As String = "Manager Name"
Public Sub DisplayName()
' Accessing the shadowed property
Console.WriteLine($"Manager Name: {Me.Name}") ' Refers to Manager's Name
' Accessing the base class property using MyBase
Console.WriteLine($"Base Employee Name: {MyBase.Name}") ' Refers to Employee's Name
End Sub
End Class
' Example usage:
' Dim emp As New Employee()
' emp.Name = "John Doe"
' Console.WriteLine(emp.Name) ' Output: John Doe
' Dim mgr As New Manager()
' mgr.Name = "Alice Smith" ' Sets Manager's Name
' mgr.DisplayName()
' Output:
' Manager Name: Alice Smith
' Base Employee Name: Unknown
Abstract Classes and Methods
An abstract class is a class that cannot be instantiated directly. It serves as a base class for other classes and typically contains one or more abstract members.
An abstract method is a method declared in an abstract class but has no implementation. Derived classes are required to provide an implementation for all abstract methods inherited from the base class.
Use the MustInherit
keyword for abstract classes and MustOverride
for abstract methods.
' Abstract base class
Public MustInherit Class Animal
Public Property Name As String
' Abstract method - must be implemented by derived classes
Public MustOverride Sub MakeSound()
Public Sub Eat()
Console.WriteLine($"{Name} is eating.")
End Sub
End Class
' Derived class implementing the abstract method
Public Class Dog
Inherits Animal
Public Overrides Sub MakeSound()
Console.WriteLine("Woof!")
End Sub
End Class
' Derived class implementing the abstract method
Public Class Cat
Inherits Animal
Public Overrides Sub MakeSound()
Console.WriteLine("Meow!")
End Sub
End Class
' Example usage:
' Dim myDog As New Dog()
' myDog.Name = "Buddy"
' myDog.MakeSound() ' Output: Woof!
' myDog.Eat() ' Output: Buddy is eating.
' Dim myCat As New Cat()
' myCat.Name = "Whiskers"
' myCat.MakeSound() ' Output: Meow!
' Dim genericAnimal As New Animal() ' Error: Cannot create an instance of an abstract class.
Sealed Classes
A sealed class is a class that cannot be inherited from. This is useful when you want to prevent further extension of a class's functionality or to improve performance by allowing the compiler to perform certain optimizations.
Use the NotInheritable
keyword to define a sealed class.
' A sealed class that cannot be inherited
Public NotInheritable Class UtilityHelper
Public Shared Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
Public Shared Function Subtract(a As Integer, b As Integer) As Integer
Return a - b
End Function
End Class
' Trying to inherit from a sealed class will result in a compile-time error:
' Public Class MyUtility
' Inherits UtilityHelper ' Error: 'UtilityHelper' is not allowed to be inherited.
' End Class