Quick N Dirty OOP Inheritance

Submitted on: 1/7/2015 7:08:00 AM
By: James Vincent Carnicelli (from psc cd)  
Level: Intermediate
User Rating: By 2 Users
Compatibility: VB 3.0, VB 4.0 (16-bit), VB 4.0 (32-bit), VB 5.0, VB 6.0, VB Script, ASP (Active Server Pages)
Views: 1262
     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.

				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.

    Other 20 submission(s) by this author


    Report Bad Submission
    Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
    This submission should be removed because:

    Your Vote

    What do you think of this article (in the Intermediate category)?
    (The article with your highest vote will win this month's coding contest!)
    Excellent  Good  Average  Below Average  Poor (See voting log ...)

    Other User Comments

     There are no comments on this submission.

    Add Your Feedback
    Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)

    To post feedback, first please login.