Interfaces and Abstract Classes

20.1 Interfaces

VB requires explicit Implements clauses on each member. Visual Studio generates the stubs when you press Enter after Implements IShape.

One method can implement several interface members: Implements IA.Run, IB.Execute.

VB can consume default interface methods defined in C#, but can't declare them.

Public Interface IShape
    ReadOnly Property Name As String
    Function Area() As Double
    Function Perimeter() As Double
End Interface

Public Interface IDrawable
    Sub Draw()
End Interface

Public Class Circle
    Implements IShape, IDrawable

    Public Property Radius As Double

    Public ReadOnly Property Name As String Implements IShape.Name
        Get
            Return "Circle"
        End Get
    End Property

    Public Function Area() As Double Implements IShape.Area
        Return Math.PI * Radius ^ 2
    End Function

    Public Function Perimeter() As Double Implements IShape.Perimeter
        Return 2 * Math.PI * Radius
    End Function

    Public Sub Render() Implements IDrawable.Draw        ' the member name can differ from the interface name
        Console.WriteLine($"Drawing circle r={Radius}")
    End Sub
End Class

Dim shapes As New List(Of IShape) From {New Circle With {.Radius = 2}}
For Each s In shapes
    Console.WriteLine($"{s.Name}: {s.Area():F2}")
Next

20.2 Abstract (MustInherit) Classes

Public MustInherit Class Employee
    Public Property Name As String
    Public MustOverride Function CalculatePay() As Decimal     ' abstract method
    Public Overridable Function GetTitle() As String
        Return "Employee"
    End Function
    Public Function PaySlip() As String                         ' template method pattern
        Return $"{GetTitle()} {Name}: {CalculatePay():C}"
    End Function
End Class

Public Class SalariedEmployee
    Inherits Employee
    Public Property AnnualSalary As Decimal
    Public Overrides Function CalculatePay() As Decimal
        Return AnnualSalary / 12
    End Function
End Class

Public Class HourlyEmployee
    Inherits Employee
    Public Property Rate As Decimal
    Public Property Hours As Decimal
    Public Overrides Function CalculatePay() As Decimal
        Return Rate * Hours
    End Function
    Public Overrides Function GetTitle() As String
        Return "Contractor"
    End Function
End Class

20.3 Interface vs Abstract Class

No (except consumed default methods) Yes (implement many) No (inherit one)

Capabilities/contracts (IComparable, IDisposable) Shared base behavior

20.4 Important .NET Interfaces

IComparable(Of T) (sorting), IComparer(Of T), IEquatable(Of T), IEnumerable(Of T) / IEnumerator(Of T) (For Each), IDisposable (Using), ICloneable, INotifyPropertyChanged (data binding), IFormattable.

Public Class Student
    Implements IComparable(Of Student)
    Public Property Name As String
    Public Property Grade As Integer
    Public Function CompareTo(other As Student) As Integer Implements IComparable(Of Student).CompareTo
        Return Grade.CompareTo(other.Grade)
    End Function
End Class
students.Sort()                                       ' uses CompareTo