Inheritance
Prerequisites: Constructors and shared members
Inheritance lets a class build on another: the new class (derived class) gets all the members of the base class and can add or change behavior.
Public Class Animal
Public ReadOnly Property Name As String
Public Sub New(name As String)
Me.Name = name
End Sub
Public Overridable Function Sound() As String
Return "..."
End Function
Public Function Speak() As String
Return $"{Name} says {Sound()}"
End Function
End Class
Public Class Dog
Inherits Animal
Public Sub New(name As String)
MyBase.New(name)
End Sub
Public Overrides Function Sound() As String
Return "Woof"
End Function
End Class
Public Class Puppy
Inherits Dog
Public Sub New(name As String)
MyBase.New(name)
End Sub
Public Overrides Function Sound() As String
Return MyBase.Sound().ToLower() & "!"
End Function
End Class
Module Program
Sub Main()
Dim animals As Animal() = {New Animal("Generic"), New Dog("Rex"), New Puppy("Bit")}
For Each a In animals
Console.WriteLine(a.Speak())
Next
End Sub
End Module
Generic says ...
Rex says Woof
Bit says woof!
Inherits Animalmust be the first line of the class.Overridableallows a method to be replaced;Overridesreplaces it. (C#'svirtualandoverride.)MyBasecalls the base class — its constructor (MyBase.New) or its version of a method.Speakis defined once inAnimalbut calls the rightSoundfor each object. This is polymorphism.
Abstract classes
MustInherit makes a class that can't be created directly, and
MustOverride declares a method each subclass must implement:
Public MustInherit Class Shape
Public MustOverride Function Area() As Double
Public Function Describe() As String
Return $"{Me.GetType().Name} with area {Area():F2}"
End Function
End Class
Public Class Circle
Inherits Shape
Public Property Radius As Double
Public Overrides Function Area() As Double
Return Math.PI * Radius ^ 2
End Function
End Class
Public Class Square
Inherits Shape
Public Property Side As Double
Public Overrides Function Area() As Double
Return Side * Side
End Function
End Class
Module Program
Sub Main()
Dim shapes As New List(Of Shape) From {New Circle With {.Radius = 1}, New Square With {.Side = 2}}
For Each s In shapes
Console.WriteLine(s.Describe())
Next
End Sub
End Module
Circle with area 3.14
Square with area 4.00
Checking and converting types
Public Class Animal
End Class
Public Class Dog
Inherits Animal
Public Function Fetch() As String
Return "fetching!"
End Function
End Class
Module Program
Sub Main()
Dim a As Animal = New Dog()
If TypeOf a Is Dog Then
Dim d = DirectCast(a, Dog)
Console.WriteLine(d.Fetch())
End If
Dim maybeDog = TryCast(New Animal(), Dog)
Console.WriteLine(maybeDog Is Nothing)
End Sub
End Module
fetching!
True
DirectCast converts to a derived type and throws if it's wrong;
TryCast returns Nothing instead.
NotInheritable and Shadows
NotInheritable Classprevents inheritance (C#'ssealed).NotOverridable Overridesstops further overriding in subclasses.Shadowshides a base member instead of overriding it — rarely what you want; the compiler warns when you do it by accident.
Keep hierarchies shallow. When classes only need to share a capability, an interface (next lesson) is usually a better fit than a base class.