' Σε Visual Basic 2008 
Option Strict On
Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
#If DEBUG Then
        ' Δεν χρειάζεται να βάζουμε πάντα breakpoints στο .net από το IDE
        ' γίνεται και από κώδικα
        'If Debugger.IsAttached Then Debugger.Break()
#End If
        Dim a As New PersonWithModuleInsert("Dimitris")
        Dim b As New PersonWithSharedInsert("Giorgos", 18) With {.Telephone = "(+30) 210 78459345"} ' ή αλλιώς b.Telephone = "(+30) 210 78459345"
        Dim c As New PersonWithInstanceInsert("Panagiotis", 22)
        ' κάνε nouse Hover (όταν κάνεις debug) πάνω από κάθε object (a, b ,c) γιά να δεις τις επιπλέον πληροφορίες που προσθέσαμε.
#If DEBUG Then
        Debug.WriteLine(CType(a, String))
        Debug.WriteLine(a.ToString())
#End If
        ' Που είναι το module που κάνει insert το Person στην βάση; Ουφ το βρήκα επιτέλους :)
        ModPersonTools.Insert(a)
        ' Αντί να ψάχνεις το Module με τις συναρτήσεις γιά το κάθε Person το έχεις έτοιμο από το class Person_WithSharedInsert
        PersonWithSharedInsert.Insert(b)
        ' Τι;, κάθε φορά θα "σηκώνω" ένα function στην μνήμη (μετά από κάθε new Instance) γιά να κάνει Insert; γιατί;
        c.Insert()
    End Sub
End Class ' Form1
Public Enum Sex
    Male
    Female
    Unknown
End Enum ' Sex
Public MustInherit Class Human
    Private _Age As Integer
    Public Property Age() As Integer
        Get
            Return _Age
        End Get
        Set(ByVal value As Integer)
            _Age = value
        End Set
    End Property
    Private _Sex As Sex = Sex.Unknown
    Public Property Sex() As Sex
        Get
            Return _Sex
        End Get
        Set(ByVal value As Sex)
            _Sex = value
        End Set
    End Property
End Class ' Human
Public MustInherit Class PersonBase
    Inherits Human
#Region "public:"
    Private _Name As String
    Public Property Name() As String
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
        End Set
    End Property
    Private _Telephone As String
    Public Property Telephone() As String
        Get
            Return _Telephone
        End Get
        Set(ByVal value As String)
            _Telephone = value
        End Set
    End Property
    Public Shared Narrowing Operator CType(ByVal person As PersonBase) As String
        Return PersonBase._Info(person)
    End Operator
    ' Αυτό το function είναι κληρονομημένο από το Object.
    ' Όταν κάνεις debug θα δεις επίσης ότι σου δίνει και άλλες πληροφορίες που κάνουν
    ' την δουλεία σου ευκολότερη χωρίς να χρειάζεται να κάνεις expand το κάθε person class 
    ' όταν κάνεις mouse hover
    Public Overrides Function ToString() As String
        Return "Type Info: " & MyBase.ToString() & " " & PersonBase._Info(Me)
    End Function
    Public ReadOnly Property Identity() As String
        Get
            Return _Identity
        End Get
    End Property
#End Region
#Region "protected:"
    Protected Sub New(ByVal name As String)
        Me._CommonConstructor(name)
    End Sub
    Protected Sub New(ByVal name As String, ByVal age As Integer)
        MyBase.Age = age
        Me._CommonConstructor(name)
    End Sub
#End Region
#Region "private:"
    Private Sub _CommonConstructor(ByVal Name As String)
        Me._Name = Name
        _ID += 1I
        Me._Identity = _PREFIX & _ID.ToString(System.Globalization.CultureInfo.InvariantCulture)
    End Sub
    Private Const _PREFIX As String = "PERSON_"
    Private _Identity As String = String.Empty
    ' Δοκίμασε να βγάλεις το Shared
    ' τότε Όλα τα Objects θα έχουν ID 0 :(
    Private Shared _ID As Integer = 0
    Private Shared Function _Info(ByVal person As PersonBase) As String
        Dim sb As New System.Text.StringBuilder
        Dim sInfo As String = Nothing
        sb.Append("ID: ").Append(person.Identity)
        sb.Append(", Name: ").Append(person.Name)
        sb.Append(", Sex: ").Append(person.Sex.ToString)
        sb.Append(", Age: ").Append(person.Age)
        sb.Append(", Telephone: ").Append(person.Telephone)
        sInfo = sb.ToString
        sb.Length = 0
        sb = Nothing
        Return sInfo
    End Function
#End Region
End Class ' PersonBase
Public Class PersonWithModuleInsert
    Inherits PersonBase
    Public Sub New(ByVal name As String)
        MyBase.new(name)
    End Sub
    Public Sub New(ByVal name As String, ByVal age As Integer)
        MyBase.New(name, age)
    End Sub
End Class
' Γιατί να φτιάχνουμε modules
' που φορτώνονται στην μνήμη χωρίς να χρησιμοποιούνται;
Public Module ModPersonTools
    Public Function Insert(ByVal thePerson As PersonBase) As Integer
        ' TODO insert to DB
        Return 1
    End Function
End Module ' ModPersonTools
' Αυτός ο τρόπος είναι κατά την γνώμη μου ο καλύτερος 
Public Class PersonWithSharedInsert
    Inherits PersonBase
    Public Sub New(ByVal name As String)
        MyBase.new(name)
    End Sub
    Public Sub New(ByVal name As String, ByVal age As Integer)
        MyBase.New(name, age)
    End Sub
    Public Shared Function Insert(ByVal thePerson As PersonBase) As Integer
        ' TODO insert to DB
        Return 1
    End Function
End Class ' PersonWithSharedInsert
Public Class PersonWithInstanceInsert
    Inherits PersonBase
    Public Sub New(ByVal name As String)
        MyBase.new(name)
    End Sub
    Public Sub New(ByVal name As String, ByVal age As Integer)
        MyBase.New(name, age)
    End Sub
    Public Function Insert() As Integer
        ' TODO insert to DB
        Return 1
    End Function
End Class ' PersonWithInstanceInsert