Search Tools Links Login

Quick N Dirty OOP Inheritance

VB (version 6 and earlier) doesn't offer any decent way to create a new class that inherits public members from an existing one. Here's an easy, if inelegant, way to simulate inheritance.

Original Author: James Vincent Carnicelli


Most programmers who have any understanding of what object-oriented programming (OOP) is about have heard terms like "inheritance" and "subclassing". The goal is to create a new class starting not from scratch, but using an existing class as the foundation. While many other languages like C++ and Java offer inheritance models, Visual Basic 6 and earlier versions don't in any decent sense. The closest it comes to it is the use of the messy "Implements" directive.

What most programmers familiar with OOP don't know is that there are two basic relationships with which to implement inheritance: "is a" and "has a". Let's say for example we have the following three classes: Animal, Dog, and Beagle. We want Dog to inherit public members from Animal and Beagle to inherit them from Dog. Speaking "purely" of OOP, we would say that we would say that a Beagle is a Dog. The alternative would be to say that a Beagle has a Dog. In English, this sounds like nonsense, but bear with me. If you want to gain the functionality of one class, it suffices to simply instantiate it, which is another way of saying the first class would have an instance of the other. Consider the following illustration:


  • BaseClass As

  • Dog

  • BaseClass As

  • Animal

  • Species As String

  • HasFleas As Boolean

  • HasLongEars As Boolean
  • HasFleas As Boolean

  • Note the "overloaded" .HasFleas property in both Dog and Beagle. Here are the equivalent VB class modules:

    Class: Animal

    Private propSpecies As String

    Public Property Get Species() As String
        Species = propSpecies
    End Property
    Public Property Let Species(newSpecies As String)
        propSpecies = newSpecies
    End Property

    Class: Dog

    Private BaseClass As Animal
    Private propHasFleas As Boolean

    Public Property Get B() As Animal
        Set B = BaseClass
    End Property

    Public Property Get HasFleas() As Boolean
        HasFleas = propHasFleas
    End Property
    Public Property Let HasFleas(newHasFleas As Boolean)
        propHasFleas = newHasFleas
    End Property

    Private Sub Class_Initialize()
        Set BaseClass = New Animal
        BaseClass.Species = "Canus"
    End Sub

    Class: Beagle

    Private BaseClass As Dog
    Private propHasFleas As Boolean
    Private propHasLongEars As Boolean

    Public Property Get B() As Dog
        Set B = BaseClass
    End Property

    Public Property Get HasFleas() As Boolean
        HasFleas = True
    End Property

    Public Property Get HasLongEars() As Boolean
        HasLongEars = True
    End Property

    Private Sub Class_Initialize()
        Set BaseClass = New Dog
    End Sub

    So when we create a Beagle object, it's creating a Dog object internally, which in tun is creating an Animal object inside itself. So if Beagle "inherits" functionality from Dog and Dog likewise from Animal, how to we use this inherited functionality in our code? One answer which is elegant from the Beagle class's user's (programmer's) point of view would be to reproduce properties, methods, and events with the same names as all of what's being "inherited". So Beagle, for example, would have a .Species property to mirror the one in Animal which would simply delegate the work of storage and/or processing to the Animal class. But then, the chore of creating these mirror members can really suck if you're making a class that adds only two new members to a class that already has two dozen you want to inherit.

    A simpler way, which is admittedly a little messier for the end programmer, is to give him a handle to the "base class" object so he can directly access its members. We've done this by adding a .B -- short for "Base Class" -- property. So to find out what species our beagle is we might say TheSpecies = MyBeagle.B.B.Species. Granted, this isn't as elegant as TheSpecies = MyBeagle.Species, but this construct is invalid in our case. Suffice it to say that using the slighly ugly .B property to get to an object's "base class" works and doesn't take much effort on your part to implement. It's also worth pointing out that you can do multiple inheritance this way, too, so long as you come up with a different property name for each of the base classes. You might use .B1 and .B2 or perhaps opt to go with more explicitly named properties like .BcDog and .BcAnimal.

    The key to making this work for the user, who most likely won't care how your class is implemented, is to instruct him to look for a given property or method in your object, first, and then to look for a property or method in the object .B refers to if he can't find it in your class directly. This is especially important if you overload a given function, as in our case where .HasFleas is implemented in the Dog class but also in the Beagle class. The user of the Beagle class can refer, then, to .HasFleas to get your overriding property or to the .B.HasFleas property to refer to the overridden version of the property.

    While this mildly messy of approach may not be an elegant one if you're distributing polished products to clients or trying to set industry standards, it's an excellent way to help organize and maintain the inner workings of your more complicated VB projects.

    In summary, although VB doesn't have a clean implementation of the traditional OOP inheritance ("is a") concept, you can simulate it using a "has a" relationship. The syntax for using the "inherited" members may seem a bit awkward, but the benefit is a simpler implementation for you and a greater ease of maintaining your code, both encouraging you to better modularize your code toward the ends modularization has long promised.

    About this post

    Posted: 2002-06-01
    By: ArchiveBot
    Viewed: 105 times


    Visual Basic 6


    No attachments for this post

    Loading Comments ...


    No comments have been added for this post.

    You must be logged in to make a comment.