Subclasses and Inheritance
In Designing an Xbasic Class we offhandedly asked "Do we need 14 subclasses, one for each different database API?" and answered "It's one way to go." Let's explain what subclasses are, and why are they useful. Subclasses are classes derived from a base class. In Xbasic, that is done with the INHERITS keyword:
DEFINE CLASS MySubClass INHERITS MyBaseClass
Subclasses inherit the capabilities of the base class, which they can use, modify, add to, or override. A subclass can be differentiated from its base class by
adding member variables (properties)
adding member functions (methods)
redefining (overriding) member functions inherited from the base class
Subclasses can themselves become the base classes for other classes. In our stored procedure example, we discovered that some databases use the CALL keyword to invoke a stored procedure, while other databases use the EXEC keyword to invoke a stored procedure. We could define a class hierarchy that reflects this:
DEFINE CLASS StoredProc ... END CLASS DEFINE CLASS ExecSP INHERITS StoredProc DIM m_SP_Keyword as C = "EXEC" ... END CLASS DEFINE CLASS CallSP INHERITS StoredProc DIM m_SP_Keyword as C = "CALL" ... END CLASS DEFINE CLASS SQLServer_SP INHERITS ExecSP ... END CLASS DEFINE CLASS Sybase_SP INHERITS ExecSP ... END CLASS DEFINE CLASS MySQL_SP INHERITS CallSP ... END CLASS DEFINE CLASS Oracle_SP INHERITS CallSP ... END CLASS DEFINE CLASS DB2_SP INHERITS CallSP ... END CLASS ...
Then the functionality common to all databases would be implemented in StoredProc, the functionality common to all databases that use the EXEC keyword would be implemented in ExecSP, the functionality common to all databases that use the CALL keyword would be implemented in CallSP, and the datatabase-specific functionality would be implemented in SQLServer_SP, MySQL_SP, and so on.
If we think about our current example, we can say accurately that SQL Server is a database. In object-oriented design terms, this "is a" relationship is appropriate for inheritance. Let's think about a different area. A Ford F150 truck is a type of motor vehicle. So an F150 class can inherit from a Truck class, which can inherit from a MotorVehicle class. All well and good. On the other hand, a motor vehicle has a driver, but is not a kind of driver. So instead of inheritance, we would use a different mechanism to express the relationship: the MotorVehicle class would have a member variable which is an instance of the Driver class.
DEFINE CLASS Driver ... END CLASS DEFINE CLASS MotorVehicle ... DIM m_driver AS Driver ... END CLASS
Before using class inheritance, make sure that the relationship between the classes can fairly be described as is-a rather than has-a.