In this second of a series on object-oriented programming in .Net, you'll learn the basics of inheritance, class properities, class methods, and overrides. Oh, so
that's how it works!
This is the second in a series of three articles on object-oriented programming in .Net. This time, you learn the basics of inheritance, class properities, class methods, and overrides.
Inheritance
One of the most important capabilities of OOP is inheritance, the ability to define a new class based on an existing class. Inheritance is sometimes referred to as subclassing. The new class inherits all of the base class's interface elements and behaviors. In other words, the new class, called a derived class, starts out as a copy of the base class under a different name. Then you can modify it as needed for the program. The base class can be a class in the .Net Framework or a class which you or another programmer created.
If you examine the class hierarchy in the .Net Framework, you'll see that it relies heavily on inheritance. Every class in the Framework inherits from the System.Object class, either directly or indirectly (that is, thru one or more additional layers of inheritance). Classes you define can inherit from other classes you created or from classes in the .Net Framework.
Inheritance is an extremely powerful technique. It saves an enormous amount of coding, because it lets you easily reuse code.
Let's look at an example. Suppose you are writing an application to keep track of an manage your organization's employees. There are three categories of employees: hourly workers, salaried workers, and independent contractors. Your first thought might be to define a class for each category but, putting on your thinking cap, you realize that while the three categories have differences they also have many similarities. For example, all three require properties for storing an employee's name, address, and Social Security number. Therefore, you start by defining a Person class that has all these common elements. Then you use Person as the base class for each of three new classes, HourlyEmployee, SalariedEmployee, and Contractor. Each of these classes will inherit the common members from Person, and you can then add the new members that are unique to each type of employee. Note that in this example the Person class is never used directly by the program; its function is only to serve as a base class.
To implement inheritance, use the Inherits keyword in the class at the start of the definition:
Public Class DerivedClass
Inherits BaseClass
...
End Class
Of course, BaseClass must be accessible and, depending on how you are using namespaces in the project, may require a namespace qualifier.
Because of the importance of inheritance, you have some flexibility in defining how it can and cannot be used in specific situations. They are:
- You can define a class that cannot be inherited using the
NotInheritable modifier. Such a class can be instantiated and used in a program but cannot serve as a base class.
- You can define a class that must be inherited using the
MustInherit modifier. Such a class cannot be instantiated in a program but can serve as a base class. Sometimes the term abstract class is used for this.
Defining Class Properties
Recall that a property is data storage within an object. A roperty can be any of VB's data types including arrays and other objects. There are two ways to define a property in a class. The simpler way is to declare a public variable within the class:
Public Class SomeClass
Public Name As String
...
End Class
Now the variable, or property, is available for use with objects based on the class using the standard ObjectName.PropertyName syntax::
Dim obj As New SomeClass
obj.Name = "Jack"
A second and more flexible way to define class properties is with property procedures. You start by declaring a variable in the class to hold the property value, but this time declare it as Private so it is not available to code outside the class. Then you write a property procedure that provides the interface for the property. It looks like this:
Public Property PropertyName As Type
Set(ByVal Value As Type)
VarName = Value
End Set
Get
PropertyName=VarName
End Get
End Property
In this example, PropertyName is the name of the property, Type is the data type of the property, and VarName is the name of the private variable you declared to hold the property value. Here's how it works. When a program sets the value of the property, the property value is passed to the Set...End Set block, which stores the value in the variable. When a program reads the value of the property, the Get...End Get block is called which retrieves the property value from the variable and returns it to the calling code.
So far, using a property procedure does not seem any different from simply declaring a Public variable for a property. The added flexibility comes in two ways. First, you can put additional code in the Set or Get block to perform other actions when the property is set or read, such as value checking (making sure the property value is within permitted limits) or essentially any other action you want the object to take at the time. Second, you can define a property as being read-only or write-only, as follows:
- For a read-only property, include the
ReadOnly modifier in the first line of the property procedure and omit the Set block.
- For a write-only property, include the
WriteOnly modifier in the first line of the property procedure and omit the Get block.
For example, here's a class with a single read-only property:
Public Class SomeClass
Private pData As String
Public ReadOnly Property Data As String
Get
Data = pData
End Get
End Property
End Class
Properties can also be object references and arrays. To implement a property that is an array the property procedure must be passed the index of the array element to access. Here's how that is done:
Public Class ArrayProperty
Private pData(100) As Integer
Public Property Data(ByVal Idx As Integer) As Integer
Get
Data = pData(Idx)
End Get
Set(ByVal Value As Integer)
pData(Idx) = Value
End Set
End Property
End Class
The you would use the property like this:
Dim obj As New ArrayProperty
obj.Data(5) = 22
In a real program, you would include code in the property procedure to validate that the value of the index is within the allowed bounds for the array.
Defining Class Methods
A method is a procedure within a class. As with regular procedures, there are two types of methods: those that return a value, defined with the Function keyword, and those that don't, defined with the Sub keyword. The syntax for creating class methods is exactly the same as for writing regular Visual Basic.Net procedures, so I will not go into the details
here. Here's an example of a class with two methods:
Public Class SimpleMath
Public Function HalfOf(Val As Double) As Double
HalfOf = Val / 2
End Function
Public Function Squared(Val As Double) As Double
Squared = Val * Val
End Function
End Class
If you want the method to be available to code outside the class, be sure to make it Public (which is the default). You can declare a method as Private, in which case it will be available only to code within the class itself. Private methods are sometimes called helper methods.
Overriding Class Members
As I have said, a derived class automatically inherits all the members — properties and methods — of its base class. What if one or more of those inherited members is not exactly what you need? For instance, perhaps the base class has a Print method that does not operate just the way you want, and you would like to write your own Print method to replace the inherited one. This is called overriding. There are several modifiers that you can use to control and implement overrides:
- Overridable. Used in a base class to specify that a property or method can be overridden in a derived class.
- Overrides. Used in a derived class to specify that a property of method is overriding an inherited property or method.
- NotOverridable. Used in a base class to specify that a property or method cannot be overridden in a derived class. This is the default for public methods.
- MustOverride. Used in a base class to specify that a property or member must be overridden in a derived class. Applicable only in abstract classes (those defined with the MustInherit modifier).
In the next article of this series, I will wrap up my treatment of OOP in .Net.