Home

Class Abstraction and Shadowing

Fundamentals of Class Abstraction

Overriding a Member of a Class

As mentioned in the previous lesson, when creating a class that would serve as a parent to other classes, to indicate that a member can be overridden in a child class, mark that member with the Overridable keyword. In the child class, you don't have to create a member that corresponds to the overridable member of the parent class. If the child class must have a member of the same name and the same syntax as the overridable member of the parent class, you should override it (if you just create it without overriding, you will receive a warning but the code should work just fine).

To override a member, in the child class, create a member with the same name and the same syntax as the overridable member of the parent class but start it with the Overrides keyword. Then, in the body of the member, create the new behavior you want. Here is an example:

<%@ Page Language="VB" %>

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public Class WorkDay
    Protected time As Double
    Protected hSalary As Double

    Public Sub New(ByVal worktime As Double, ByVal salary As Double)
        time = worktime
        hSalary = salary
    End Sub

    Public Property TimeWorked As Double
        Get
            Return time
        End Get
        Set(value As Double)
            time = value
        End Set
    End Property

    Public Overridable ReadOnly Property RegularTime As Double
        Get
            Return TimeWorked
        End Get
    End Property

    Public Overridable ReadOnly Property RegularPay As Double
        Get
            Return RegularTime * hSalary
        End Get
    End Property
End Class

Public Class OvertimeWork
    Inherits WorkDay

    Public Sub New(ByVal worktime As Double, ByVal salary As Double)
        MyBase.New(worktime, salary)
    End Sub

    Private ReadOnly Property OvertimeSalary
        Get
            Return hSalary * 1.50
        End Get
    End Property

    Public Overrides ReadOnly Property RegularTime As Double
        Get
            Return If(time <= 40.00, time, 40.00)
        End Get
    End Property

    Public ReadOnly Property Overtime As Double
        Get
            Return If(time <= 40.00, 0.00, time - 40.00)
        End Get
    End Property

    Public Overrides ReadOnly Property RegularPay As Double
        Get
            Return RegularTime * hSalary
        End Get
    End Property

    Public ReadOnly Property OvertimePay As Double
        Get
            Return OvertimeSalary * Overtime
        End Get
    End Property

    Public ReadOnly Property NetPay As Double
        Get
            Return RegularPay + OvertimePay
        End Get
    End Property
End Class

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim time As Double
    Dim salary As Double

    time = If(String.IsNullOrEmpty(txtTimeWorked.Text), 0.00, CDbl(txtTimeWorked.Text))
    salary = If(String.IsNullOrEmpty(txtHourlySalary.Text), 0.00, CDbl(txtHourlySalary.Text))

    Dim pay = New OvertimeWork(time, salary)

    txtRegularTime.Text = FormatNumber(pay.RegularTime)
    txtOvertime.Text = FormatNumber(pay.Overtime)
    txtRegularPay.Text = FormatCurrency(pay.RegularPay)
    txtOvertimePay.Text = FormatCurrency(pay.OvertimePay)
    txtNetPay.Text = FormatCurrency(pay.NetPay)
End Sub
</script>
<style>
#main-title
{
    font-size: 1.08em;
    font-weight: bold;
    text-align: center;
    font-family: Georgia, Garamond, 'Times New Roman', Times, serif;
}
#central {
    width: 355px;
    margin: auto
}
#tblPayroll { width: 350px; }
</style>
<title>Employee Payroll Evaluation</title>
</head>
<body>
<form id="frmPayroll" runat="server">
<div id="central">
<p id="main-title">Employee Payroll Evaluation</p>

<asp:Table id="tblPayroll" runat="server" BorderColor="#666666" BorderStyle="Double" BorderWidth="2px">
    <asp:TableRow runat="server">
        <asp:TableCell runat="server" BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt">Time Worked:</asp:TableCell>
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">
            <asp:TextBox ID="txtTimeWorked" runat="server"></asp:TextBox>
        </asp:TableCell>
        <asp:TableCell runat="server"></asp:TableCell>
    </asp:TableRow>
    <asp:TableRow runat="server">
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">Hourly Salary:</asp:TableCell>
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">
            <asp:TextBox ID="txtHourlySalary" runat="server"></asp:TextBox></asp:TableCell>
        <asp:TableCell runat="server">
            <asp:Button ID="btnCalculate" Text="Calculate" OnClick="btnCalculateClick" runat="server" />
        </asp:TableCell>
    </asp:TableRow>
    <asp:TableRow runat="server">
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">Regular Time:</asp:TableCell>
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">
            <asp:TextBox ID="txtRegularTime" ReadOnly="true" runat="server"></asp:TextBox></asp:TableCell>
        <asp:TableCell runat="server"></asp:TableCell>
    </asp:TableRow>
    <asp:TableRow runat="server">
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">Overtime:</asp:TableCell>
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">
            <asp:TextBox ID="txtOvertime" ReadOnly="true" runat="server"></asp:TextBox></asp:TableCell>
        <asp:TableCell runat="server"></asp:TableCell>
    </asp:TableRow>
    <asp:TableRow runat="server">
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">Regular Pay:</asp:TableCell>
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">
            <asp:TextBox ID="txtRegularPay" ReadOnly="true" runat="server"></asp:TextBox></asp:TableCell>
        <asp:TableCell runat="server"></asp:TableCell>
    </asp:TableRow>
    <asp:TableRow runat="server">
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">Overtime Pay:</asp:TableCell>
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">
            <asp:TextBox ID="txtOvertimePay" ReadOnly="true" runat="server"></asp:TextBox></asp:TableCell>
        <asp:TableCell runat="server"></asp:TableCell>
    </asp:TableRow>
    <asp:TableRow runat="server">
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">Net Pay:</asp:TableCell>
        <asp:TableCell BorderColor="Silver" BorderStyle="Solid" BorderWidth="1pt" runat="server">
            <asp:TextBox ID="txtNetPay" ReadOnly="true" runat="server"></asp:TextBox></asp:TableCell>
        <asp:TableCell runat="server"></asp:TableCell>
    </asp:TableRow>
</asp:Table>
</div>
</form>
</body>
</html>

Here is an example of using the webpage:

Overriding a Member of a Class

Overriding a Member of a Class

Overriding a Member of a Class

Overriding a Member of a Class

Introduction to Abstract Classes

A class is referred to as abstract when it is only used to lay a foundation for other classes. In the Microsoft Visual Basic language, to create an abstract class, you must precede its Class keyword with MustInherit. Here is an example:

<script runat="server">
Public MustInherit Class Triangle

End Class
</script>

After creating a class and marking it as MustInherit, you can add and define one or more members to it.

If you create a class and mark it as MustInherit, it is considered incomplete. Because of that, although you can declare a variable of that type, you cannot initialize its instance using the New operator. Consider the following example:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public MustInherit Class Triangle

End Class
</script>
<title>Geometry: Isosceles Triangle</title>
</head>
<body>
<div align="center">
<h2>Geometry: Isosceles Triangle</h2>

<%
    Dim tri As New Triangle
%>
</body>
</html>

This would produce an error because you cannot use New to instantiate a MustInherit class. This means that, before using a MustInherit class, you must derive a class from it. Here is an example:

<head runat="server">
<script runat="server">
Public MustInherit Class Triangle

End Class

Public Class Isosceles
    Inherits Triangle

End Class
</script>

Remember that you cannot apply the New operator to an abstract class to create an object. Instead, you can declare a regular variable using the abstract class, then initialize the variable using the desired inherited class. Here is an example:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public MustInherit Class Triangle

End Class

Public Class Isosceles
    Inherits Triangle

End Class
</script>
<title>Geometry: Isosceles Triangle</title>
</head>
<body>
<div align="center">
<h2>Geometry: Isosceles Triangle</h2>

<%
    Dim tri As Triangle

    tri = New Isosceles
%>
</body>
</html>

As an alternative, you can declare the variable using the abstract class and immediately initialize it using an inherited class, on the same line. Here is an example:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public MustInherit Class Triangle

End Class

Public Class Isosceles
    Inherits Triangle

End Class
</script>
<title>Geometry: Isosceles Triangle</title>
</head>
<body>
<div align="center">
<h2>Geometry: Isosceles Triangle</h2>

<%
    Dim tri As Triangle = New Isosceles
%>
</body>
</html>

With the last two techniques, you would have access only to the members of the abstract class. The members, if any, of the inherited class would not be available. The last option is to declare the variable using the inherited class without the abstract class. In this case, the variable can access the public members of the abstract class and those of the inherited class. Here are two examples:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public MustInherit Class Triangle

End Class

Public Class Isosceles
    Inherits Triangle

End Class
</script>
<title>Geometry: Isosceles Triangle</title>
</head>
<body>
<div align="center">
<h2>Geometry: Isosceles Triangle</h2>

<%
    Dim tri As Isosceles
    tri = New Isosceles

    Dim iso As Isosceles = New Isosceles
%>
</body>
</html>

An abstract class can have regular members that can be directly accessed by child classes that inherit from the class, or an object created from the child class can access those members. Here are examples:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public MustInherit Class Triangle
    Private len As Double
    Private hgt As Double

    Public Property Length As Double
        Get
            Return len
        End Get
        Set(ByVal value As Double)
            len = value
        End Set
    End Property

    Public Property Height As Double
        Get
            Return hgt
        End Get
        Set(ByVal value As Double)
            hgt = value
        End Set
    End Property

    Public ReadOnly Property Area As Double
        Get
            Return Length * Height / 2.0
        End Get
    End Property
End Class

Public Class Isosceles
    Inherits Triangle

End Class

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim length As Double = 0.00
    Dim height As Double = 0.00
    Dim tri As New Isosceles

    If Not String.IsNullOrEmpty(txtLength.Text) Then
        length = CDbl(txtLength.Text)
    End If

    If Not String.IsNullOrEmpty(txtHeight.Text) Then
        height = CDbl(txtHeight.Text)
    End If

    tri.Length = length
    tri.Height = height

    txtArea.Text = FormatNumber(tri.Area)
End Sub
</script>
<title>Geometry: Isosceles Triangle</title>
</head>
<body>
<div align="center">
<h2>Geometry: Isosceles Triangle</h2>

<form id="frmGeometry" runat="server">
<table>
  <tr>
    <td>Length:</td>
    <td>
      <asp:TextBox runat="server"
	           id="txtLength" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Height:</td>
      <td><asp:TextBox runat="server"
                       id="txtHeight" Text="0.00"></asp:TextBox>
	<asp:Button runat="server" id="btnCalculate"
                    Text="Calculate"
                    OnClick="btnCalculateClick"></asp:Button></td>
    </tr>
    <tr>
      <td>Area:</td>
      <td><asp:TextBox runat="server"
                       id="txtArea" Text="0.00"></asp:TextBox></td>
    </tr>
  </table>
</form>
</div>
</body>
</html>

Here is an example of using the webpage:

Introduction to Abstract Classes

Introduction to Abstract Classes

Introduction to Abstract Classes

The Member Must Be Overridden

When creating a member of an abstract class, you can indicate that the member must be overridden in the class(es). In this case, every class that inherits from the MustInherit class must (also) override that particular member. To indicate this, in the abstract class, the member must be marked, or must preceded, with the MustOverride keyword. Such a member must not be defined in the abstract class. Here is an example:

<script runat="server">
Public MustInherit Class Triangle

    Public MustOverride Function CalculatePerimeter() As Double

End Class
</script>

In the same way, you can add as many members as necessary. As a result, you can mark as MustOverride the members that must be overriden and create the other members without MustOverride.

Overriding a Member of an Abstract Class

In a derived class, you must implement each member that is marked as MustOverride from the MustInherit class. You can then use the overriden member. Here is an example:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public MustInherit Class Triangle
    Private len As Double
    Private hgt As Double

    Public Property Length As Double
        Get
            Return len
        End Get
        Set(ByVal value As Double)
            len = value
        End Set
    End Property

    Public Property Height As Double
        Get
            Return hgt
        End Get
        Set(ByVal value As Double)
            hgt = value
        End Set
    End Property

    Public ReadOnly Property Area As Double
        Get
            Return Length * Height / 2.0
        End Get
    End Property

    Public MustOverride Function CalculatePerimeter() As Double
End Class

Public Class Isosceles
    Inherits Triangle

    Public Overrides Function CalculatePerimeter() As Double
        Dim side As Double

        side = Math.Sqrt((Me.Length * Me.Length) + (Me.Height * Me.Height * 4.00)) / 2.00

        Return Me.Length + side + side
    End Function
End Class

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim length As Double = 0.00
    Dim height As Double = 0.00
    Dim tri As New Isosceles

    If Not String.IsNullOrEmpty(txtLength.Text) Then
        length = CDbl(txtLength.Text)
    End If

    If Not String.IsNullOrEmpty(txtHeight.Text) Then
        height = CDbl(txtHeight.Text)
    End If

    tri.Length = length
    tri.Height = height

    txtPerimeter.Text = tri.CalculatePerimeter()
    txtArea.Text = tri.Area
End Sub
</script>
<title>Geometry: Isosceles Triangle</title>
</head>
<body>
<div align="center">
<h2>Geometry: Isosceles Triangle</h2>

<form id="frmGeometry" runat="server">
<table>
  <tr>
    <td>Length:</td>
    <td>
      <asp:TextBox runat="server"
	             id="txtLength" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Height:</td>
      <td><asp:TextBox runat="server"
                       id="txtHeight" Text="0.00"></asp:TextBox>
	<asp:Button runat="server" id="btnCalculate"
                    Text="Calculate" OnClick="btnCalculateClick"></asp:Button></td>
    </tr>
    <tr>
      <td>Perimeter:</td>
      <td><asp:TextBox runat="server"
                       id="txtPerimeter" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Area:</td>
      <td><asp:TextBox runat="server"
                       id="txtArea" Text="0.00"></asp:TextBox></td>
    </tr>
  </table>
</form>
</div>
</body>
</html>

Here is an example of using the webpage:

Introduction to Abstract Classes

Introduction to Abstract Classes

In the derived class, you can add new members (properties, methods, and/or constructors) if you judge them necessary. Here are examples:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public MustInherit Class Triangle

    Public Property Length As Double
    Public Property Height As Double

    Public MustOverride ReadOnly Property Perimeter As Double

    Public ReadOnly Property Area As Double
        Get
            Return Length * Height / 2.0
        End Get
    End Property
End Class

Public Class Right
    Inherits Triangle

    Public Sub New(ByVal length As Double, ByVal height As Double)
        MyBase.Length = length
        MyBase.Height = height
    End Sub

    Public Overrides ReadOnly Property Perimeter As Double
        Get
            Return Me.Length + Me.Height + Math.Sqrt((Me.Length * Me.Length) + (Me.Height * Me.Height))
        End Get
    End Property

    Public ReadOnly Property Hypotenuse As Double
        Get
            Return Math.Sqrt((Me.Length * Me.Length) + (Me.Height * Me.Height))
        End Get
    End Property
End Class

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim length As Double = 0.0
        Dim height As Double = 0.0
        Dim tri As Right

        If Not String.IsNullOrEmpty(txtLength.Text) Then
            length = CDbl(txtLength.Text)
        End If

        If Not String.IsNullOrEmpty(txtHeight.Text) Then
            height = CDbl(txtHeight.Text)
        End If

        tri = New Right(length, height)

        txtHypotenuse.Text = tri.Hypotenuse
        txtPerimeter.Text = tri.Perimeter
        txtArea.Text = tri.Area
End Sub
</script>
<title>Geometry: Right Triangle</title>
</head>
<body>
<div align="center">
<h2>Geometry: Right Triangle</h2>

<form id="frmGeometry" runat="server">
<table>
  <tr>
    <td>Length:</td>
    <td>
      <asp:TextBox runat="server"
	             id="txtLength" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Height:</td>
      <td><asp:TextBox runat="server"
                       id="txtHeight" Text="0.00"></asp:TextBox>
	<asp:Button runat="server" id="btnCalculate"
                    Text="Calculate" OnClick="btnCalculateClick"></asp:Button></td>
    </tr>
    <tr>
      <td>Hypotenuse:</td>
      <td><asp:TextBox runat="server"
                       id="txtHypotenuse" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Perimeter:</td>
      <td><asp:TextBox runat="server"
                       id="txtPerimeter" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Area:</td>
      <td><asp:TextBox runat="server"
                       id="txtArea" Text="0.00"></asp:TextBox></td>
    </tr>
  </table>
</form>
</div>
</body>
</html>

Here is an example of using the webpage:

Overriding a Member of an Abstract Class

Overriding a Member of an Abstract Class

The Relationship Between an Abstract and its Derived Classes

Returning an Object of a Parent Type

A function or a method can return an object based on a abstract class. When creating the function or method, specify its return type as the parent class. Here is an example:

<script runat="server">
Public MustInherit Class Triangle

End Class

Function CreateShape() As Triangle

End Function
</script>

Since you cannot simply create an object of an abstract class and use it directly, you cannot simply return an object of an abstract class from a function. As an alternative, you can declare a variable of a class that inherits from the abstract class and return that object. Then, get the return object where it is needed and use it normally. Here is an example:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public MustInherit Class Triangle

    Public Property Length As Double
    Public Property Height As Double

    Public MustOverride ReadOnly Property Perimeter As Double

    Public ReadOnly Property Area As Double
        Get
            Return Length * Height / 2.0
        End Get
    End Property
End Class

Public Class Right
    Inherits Triangle

    Public Sub New(ByVal length As Double, ByVal height As Double)
        MyBase.Length = length
        MyBase.Height = height
    End Sub

    Public Overrides ReadOnly Property Perimeter As Double
        Get
            Return Me.Length + Me.Height + Math.Sqrt((Me.Length * Me.Length) + (Me.Height * Me.Height))
        End Get
    End Property

    Public ReadOnly Property Hypotenuse As Double
        Get
            Return Math.Sqrt((Me.Length * Me.Length) + (Me.Height * Me.Height))
        End Get
    End Property
End Class

Function CreateShape() As Triangle
    Dim length As Double = 0.0
    Dim height As Double = 0.0
    Dim shape As Triangle

    If Not String.IsNullOrEmpty(txtLength.Text) Then
        length = CDbl(txtLength.Text)
    End If

    If Not String.IsNullOrEmpty(txtHeight.Text) Then
        height = CDbl(txtHeight.Text)
    End If

    shape = New Right(length, height)
    Return shape
End Function

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim tri As Triangle

    tri = CreateShape()

    txtPerimeter.Text = tri.Perimeter
    txtArea.Text = tri.Area
End Sub
</script>
<title>Geometry: Right Triangle</title>
</head>
<body>
<div align="center">
<h2>Geometry: Right Triangle</h2>

<form id="frmGeometry" runat="server">
<table>
  <tr>
    <td>Length:</td>
    <td>
      <asp:TextBox runat="server"
	             id="txtLength" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Height:</td>
      <td><asp:TextBox runat="server"
                       id="txtHeight" Text="0.00"></asp:TextBox>
	<asp:Button runat="server" id="btnCalculate"
                    Text="Calculate" OnClick="btnCalculateClick"></asp:Button></td>
    </tr>
    <tr>
      <td>Perimeter:</td>
      <td><asp:TextBox runat="server"
                       id="txtPerimeter" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Area:</td>
      <td><asp:TextBox runat="server"
                       id="txtArea" Text="0.00"></asp:TextBox></td>
    </tr>
  </table>
</form>
</div>
</body>
</html>

Here is an example of using the webpage:

Returning an Object of a Parent Type

Returning an Object of a Parent Type

Returning an Object of a Parent Type

The function must return an object based on either the abstract class or of a class that derives from it. If you create a function or a method that returns an abstract class, the resulting object can access only the member of the abstract class.

Passing a Parent Class As Argument

If you are creating a procedure, a function, or a method that receives a class as argument and that class is derived from another, you can pass the parent class as argument. In the body of the procedure, you can access the members of the parent class. Here is an example:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public MustInherit Class Triangle
    Public Property Length As Double
    Public Property Height As Double

    Public MustOverride ReadOnly Property Perimeter As Double

    Public ReadOnly Property Area As Double
        Get
            Return Length * Height / 2.0
        End Get
    End Property
End Class

Public Class Right
    Inherits Triangle

    Public Sub New(ByVal length As Double, ByVal height As Double)
        MyBase.Length = length
        MyBase.Height = height
    End Sub

    Public Overrides ReadOnly Property Perimeter As Double
        Get
            Return Me.Length + Me.Height + Math.Sqrt((Me.Length * Me.Length) + (Me.Height * Me.Height))
        End Get
    End Property

    Public ReadOnly Property Hypotenuse() As Double
        Get
            Return Math.Sqrt((Me.Length * Me.Length) + (Me.Height * Me.Height))
        End Get
    End Property
End Class

Function CreateShape() As Triangle
    Dim length As Double = 0.0
    Dim height As Double = 0.0
    Dim shape As Triangle

    If Not String.IsNullOrEmpty(txtLength.Text) Then
        length = CDbl(txtLength.Text)
    End If

    If Not String.IsNullOrEmpty(txtHeight.Text) Then
        height = CDbl(txtHeight.Text)
    End If

    shape = New Right(length, height)
    Return shape
End Function

Sub Show(ByVal geo As Triangle)
    txtPerimeter.Text = geo.Perimeter
    txtArea.Text = geo.Area
End Sub

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim tri As Triangle

    tri = CreateShape()
    Show(tri)
End Sub
</script>
<title>Geometry: Right Triangle</title>
</head>
<body>
<div align="center">
<h2>Geometry: Right Triangle</h2>

<form id="frmGeometry" runat="server">
<table>
  <tr>
    <td>Length:</td>
    <td>
      <asp:TextBox runat="server"
	                   id="txtLength" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Height:</td>
      <td><asp:TextBox runat="server"
                       id="txtHeight" Text="0.00"></asp:TextBox>
	<asp:Button runat="server" id="btnCalculate"
                    Text="Calculate" OnClick="btnCalculateClick"></asp:Button></td>
    </tr>
    <tr>
      <td>Perimeter:</td>
      <td><asp:TextBox runat="server"
                       id="txtPerimeter" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Area:</td>
      <td><asp:TextBox runat="server"
                       id="txtArea" Text="0.00"></asp:TextBox></td>
    </tr>
  </table>
</form>
</div>
</body>
</html>

Once again, remember that you can access only the members of the parent class.

Casting an Object

Casting a value consists of converting it from one type to another. We already know that the Visual Basic language provides tremendous support using conversion functions and the CType() function. When it comes to objects, the conversion is not always smooth because inheritance and abstraction bring new issues. For example, if the CType function cannot perform the conversion, it produces an error. Most of the time, the conversion fails because the value to be converted is not compatible with the target-type. To address issues related to compatibility with objects that may or may not descend from a common class, the Visual Basic language provides a function, actually an operator (in other languages such as C or C++, we call it a macro) named TryCast.

The formula to use the TryCast operator is:

Nothing = TryCast(value, target-type)

Unlike the CType() function, the TryCast operator doesn't convert a value to a specific type. Instead, it checks whether a value is compatible with a target-type and it produces a Boolean value that you can get. Here is an example:

<script runat="server">
Public MustInherit Class Triangle

End Class

Public Class Right
    Inherits Triangle

End Class

Sub Show(ByVal geo As Triangle)
    Dim result = TryCast(geo, Triangle)
End Sub
</script>

The compatibility is based on inheritance. If the value can be reconciled with the target-type, the TryCast operator indicates that the value is reconciliable with the target-type. If the conversion is not possible, the TryCast operator produces the Nothing. Therefore, when using this operator, you can find out whether it produces Nothing and take appropriate action. Remember (Lesson 12) that that you can check if something is Nothing using the Is operator. Here is an example:

<script runat="server">
Sub Show(ByVal geo As Triangle)
    Dim result = TryCast(geo, Triangle)

    If Not result Is Nothing
        txtPerimeter.Text = geo.Perimeter
        txtArea.Text = geo.Area
    End If
End Sub
</script>

Checking the Type of an Objects

To let you check whether a certain value or an object is of a certain type, the Visual Basic language provides an operator named TypeOf. The formula to use it is:

result = TypeOf value-or-object Is | IsNot type-or-class

The value-or-object can be a variable from a primitive type or a class. It is followed by either Is to check for truthfulness or IsNot to check the contrary. The type-or-class must be a either a known data type or an existing class. The TypeOf operator produces a Boolean value as True if the value-or-object is of type-or-class, or False. Here is an example:

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public Class Ellipse
    Public Property LongRadius() As Double
    Public Property ShortRadius As Double

    Public Sub New(ByVal a As Double, ByVal b As Double)
        LongRadius = a
        ShortRadius = b
    End Sub

    Public ReadOnly Property Area As Double
        Get
            Return LongRadius * ShortRadius * Math.Pi
        End Get
    End Property
End Class

Public Class Parallelogram
    Public Property Length() As Double
    Public Property Side As Double

    Public Sub New(ByVal length As Double, ByVal side As Double)
        Length = length
        Side = side
    End Sub

    ReadOnly Property Perimeter As Double
        Get
            Return (Me.Length + Me.Side) * 2.0
        End Get
    End Property

    ReadOnly Property Area As Double
        Get
            Return Me.Length * Me.Side
        End Get
    End Property
End Class

Public Sub Present(ByVal shape As Object)
    Dim ells As Ellipse
    Dim paral As Parallelogram

    If TypeOf shape Is Ellipse Then
        ells = CType(shape, Ellipse)
        txtArea.Text = ells.Area
    End If
End Sub

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim len As Double = 0.0
    Dim hgt As Double = 0.0
    ' Dim plate As Ellipse
    Dim stadium As Parallelogram

    If Not String.IsNullOrEmpty(txtLength.Text) Then
        len = CDbl(txtLength.Text)
    End If
    If Not String.IsNullOrEmpty(txtHeight.Text) Then
        hgt = CDbl(txtHeight.Text)
    End If

    plate = New Ellipse(len, hgt)
    Present(plate)

    ' stadium = New Parallelogram(len, hgt)
    ' Present(stadium)
End Sub
</script>
<title>Geometric Shape</title>
</head>
<body>
<div align="center">
<h2>Geometric Shape</h2>

<form id="frmGeometry" runat="server">
<table>
  <tr>
    <td>Length:</td>
    <td>
      <asp:TextBox runat="server"
	                   id="txtLength" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td>Height:</td>
      <td><asp:TextBox runat="server"
                       id="txtHeight" Text="0.00"></asp:TextBox>
	<asp:Button runat="server" id="btnCalculate"
                    Text="Calculate" OnClick="btnCalculateClick"></asp:Button></td>
    </tr>
    <tr>
      <td>Area:</td>
      <td><asp:TextBox runat="server"
                       id="txtArea" Text="0.00"></asp:TextBox></td>
    </tr>
    <tr>
      <td><asp:Label id="lblPerimeter" Text="Perimeter:" Visible="False" runat="server" /></td>
      <td><asp:TextBox Visible="False" runat="server"
                       id="txtPerimeter" Text="0.00"></asp:TextBox></td>
    </tr>
  </table>
</form>
</div>
</body>
</html>

Shadowing

Introduction

Re-consider the Circle and the Sphere classes from the previous lesson:

<%@ Page Language="VB" %>

<!DOCTYPE html>

<script runat="server">
Public Class Circle
    Protected Segment As Double

    Public Sub New(ByVal radius As Double)
        Me.Segment = radius
    End Sub

    Public Property Radius As Double
        Get
            Return Me.Segment
        End Get
        Set(ByVal value As Double)
            Me.Segment = value
        End Set
    End Property

    Public ReadOnly Property Diameter As Double
        Get
            Return Me.Segment * 2.0
        End Get
    End Property

    Public ReadOnly Property Circumference As Double
        Get
            Return Me.Diameter * Math.Pi
        End Get
    End Property

    Public ReadOnly Property Area As Double
        Get
            Return Me.Segment * Me.Segment * Math.Pi
        End Get
    End Property
End Class

Public Class Sphere
    Inherits Circle

    Public Sub New(ByVal radius As Double)
        MyBase.New(radius)
    End Sub

    Public ReadOnly Property Volume As Double
        Get
            Return MyBase.Segment * MyBase.Segment * MyBase.Segment * 4.0 * Math.Pi / 3.0
        End Get
    End Property
End Class

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim Area = 0.0
    Dim radius = 0.0
    Dim disc As Circle
    Dim Diameter = 0.0
    Dim Circumference = 0.0

    radius = txtRadius.Text
    disc = New Circle(radius)

    txtDiameter.Text = disc.Diameter
    txtCircumference.Text = disc.Circumference
    txtArea.Text = disc.Area
End Sub
</script>
<style>
#main-title
{
    font-size: 1.08em;
    font-weight: bold;
    text-align: center;
    font-family: Georgia, Garamond, 'Times New Roman', Times, serif;
}
#whole
{
    margin: auto;
    width:  205px;
}
</style>
<html>
<head runat="server">
<title>Geometry - Circle</title>
</head>
<body>
<p id="main-title">Geometry - Circle</p>
<form id="frmGeometry" runat="server">
<div id="whole">
 
<table>
  <tr>
    <td>Radius:</td>
    <td><asp:TextBox id="txtRadius" Width="75px" runat="server" /></td>
    </tr>
  <tr>
      <td>&nbsp;</td>
      <td><asp:Button id="btnCalculate" runat="server"
                      Text="Calculate" Width="85px"
                      OnClick="BtnCalculateClick" />
      </td>
  </tr>
    <tr>
      <td>Diameter:</td>
      <td><asp:TextBox id="txtDiameter" runat="server" /></td>
    </tr>
  <tr>
    <td>Circumference:</td>
    <td><asp:TextBox id="txtCircumference" runat="server" /></td>
  </tr>
  <tr>
    <td>Area:</td>
    <td><asp:TextBox id="txtArea" runat="server" /></td>
  </tr>
</table>
</div>
</form>
</body>
</html>

Here is an example of using the webpage:

Introduction to Shadowing

Introduction to Shadowing

Introduction to Shadowing

As you may know already, both the circle and the sphere have an area but their area are significantly different and the formulas to calculate them are not the same. In the body of the Sphere class, you can simply create a method or a property that calculates the area. Then, when you create an object of the Sphere class, you can access that area. Here is an example:

<%@ Page Language="VB" %>

<!DOCTYPE html>

<script runat="server">
Public Class Circle
    Protected Segment As Double

    Public Sub New(ByVal radius As Double)
        Me.Segment = radius
    End Sub

    Public Property Radius As Double
        Get
            Return Me.Segment
        End Get
        Set(ByVal value As Double)
            Me.Segment = value
        End Set
    End Property

    Public ReadOnly Property Diameter As Double
        Get
            Return Me.Segment * 2.0
        End Get
    End Property

    Public ReadOnly Property Circumference As Double
        Get
            Return Me.Diameter * Math.Pi
        End Get
    End Property

    Public ReadOnly Property Area As Double
        Get
            Return Me.Segment * Me.Segment * Math.Pi
        End Get
    End Property
End Class

Public Class Sphere
    Inherits Circle

    Public Sub New(ByVal radius As Double)
        MyBase.New(radius)
    End Sub

    Public ReadOnly Property Area As Double
        Get
            Return Me.Segment * Me.Segment * 4.0 * Math.Pi
        End Get
    End Property

    Public ReadOnly Property Volume As Double
        Get
            Return MyBase.Segment * MyBase.Segment * MyBase.Segment * 4.0 * Math.Pi / 3.0
        End Get
    End Property
End Class

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim Area = 0.0
    Dim radius = 0.0
    Dim Volume = 0.0
    Dim ball As Sphere
    Dim Diameter = 0.0
    Dim Circumference = 0.0

    radius = txtRadius.Text
    ball = New Sphere(radius)

    txtDiameter.Text = ball.Diameter
    txtCircumference.Text = ball.Circumference
    txtArea.Text = ball.Area
    txtVolume.Text = ball.Volume
End Sub
</script>
<style>
#main-title
{
    font-size: 1.08em;
    font-weight: bold;
    text-align: center;
    font-family: Georgia, Garamond, 'Times New Roman', Times, serif;
}
.tblCircle { width: 200px; }
#whole
{
    margin: auto;
    width:  205px;
}
</style>
<html>
<head runat="server">
<title>Geometric Volumes - Sphere</title>
</head>
<body>
    <p id="main-title">Geometric Volumes - Sphere</p>
    <form id="frmGeometry" runat="server">
    <div id="whole">
 
<table class="tblCircle">
  <tr>
    <td>Radius:</td>
    <td><asp:TextBox id="txtRadius" Width="75px" runat="server" /></td>
    </tr>
  <tr>
      <td>&nbsp;</td>
      <td><asp:Button id="btnCalculate" runat="server"
                      Text="Calculate" Width="85px"
                      OnClick="BtnCalculateClick" />
      </td>
  </tr>
    <tr>
      <td>Diameter:</td>
      <td><asp:TextBox id="txtDiameter" runat="server" /></td>
    </tr>
  <tr>
    <td>Circumference:</td>
    <td><asp:TextBox id="txtCircumference" runat="server" /></td>
  </tr>
  <tr>
    <td>Area:</td>
    <td><asp:TextBox id="txtArea" runat="server" /></td>
  </tr>
  <tr>
    <td>volume:</td>
    <td><asp:TextBox id="txtVolume" runat="server" /></td>
  </tr>
</table>
</div>
</form>
</body>
</html>

Here is an example of using the webpage:

Introduction to Shadowing

Introduction to Shadowing

Shadowing a Member of a Class

The code works without any problem and it produces an accurate area of a sphere. If you run that code in a programming environment that can debug code such as Microsoft Visual Studio, you would receive a warning basically asking you whether you are sure of the Area you are trying to access from a Sphere object. If you derive a class a create a member that has the same name and the same access level as a member of the parent class, you must indicate whether the member in the derived class is a new implementation of the member of the same name in the parent class. If that's the case, you must indicate that the member of the derived class "shadows" the member of the parent class. In other words, the member of the child class is a "New" definition.

To indicate that a member of a derived class shadows a member of the parent class, in the child class, precede the name of the member with the Shadows keyword. When doing this, this, there must be a member that has the same name and the same access level as the new member you are creating. Here is an example:

<script runat="server">
Public Class Circle
    . . .

    Public ReadOnly Property Area As Double
        Get
            Return Me.Segment * Me.Segment * Math.Pi
        End Get
    End Property
End Class

Public Class Sphere
    Inherits Circle

    Public Sub New(ByVal radius As Double)
        MyBase.New(radius)
    End Sub

    Public Shadows ReadOnly Property Area As Double
        Get
            Return Me.Segment * Me.Segment * 4.0 * Math.Pi
        End Get
    End Property

    Public ReadOnly Property Volume As Double
        Get
            Return MyBase.Segment * MyBase.Segment * MyBase.Segment * 4.0 * Math.Pi / 3.0
        End Get
    End Property
End Class
</script>

Inheritance and the .NET Framework

Object: The Ancestor to all Classes

The .NET Framework is the main library used by the Visual Basic programming language. To support this functionality, the .NET Framework provides a rich set of classes (and namespaces).

At the highest level, the library provides the Object class that serves as the common ancestor to all classes used in the .NET Framework. In fact, any time you create a class to use in your Visual Basic project, the class is automatically derived from Object. Consider the following Square class:

<%@ Page Language="VB" %>

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
Public Class Square
        Private sd As Double

        Public Sub New(ByVal side As Double)
            Me.sd = side
        End Sub

        Public ReadOnly Property Side As Double
            Get
                If sd < 0.00 Then
                    Return 0.00
                Else
                    Return sd
                End If
            End Get
        End Property

        Public ReadOnly Property Perimeter As Double
            Get
                Return sd * 4.0
            End Get
        End Property

        Public ReadOnly Property Area As Double
            Get
                Return sd * sd
            End Get
        End Property
End Class

Sub btnCalculateClick() Handles btnCalculate.Click
        Dim plate As Square
        Dim side As Double

        If String.IsNullOrEmpty(txtSide.Text) Then
            side = 0.00
        Else
            side = CDbl(txtSide.Text)
        End If

        plate = New Square(side)

        txtPerimeter.Text = Format(plate.Perimeter, "standard")
        txtArea.Text = Format(plate.Area, "STANDARD")
End Sub
</script>
<style>
#container
{
    margin: auto;
    width:  305px;
}
#estimation {  width: 300px; }
</style>
<title>Geometry - Square</title>
</head>
<body>
<form id="frmGeometry" runat="server">
<div id="container">

<h2>Geometry - Square</h2>

<table id="estimation">
  <tr>
    <td><b>Side:</b></td>
    <td><asp:TextBox id="txtSide" Width="75px" runat="server"></asp:TextBox>
        <asp:Button id="btnCalculate" Text="Calculate" runat="server" />
    </td>
  </tr>
  <tr>
    <td><b>Perimeter:</b></td>
    <td><asp:TextBox id="txtPerimeter" Width="75px"
                     runat="server"></asp:TextBox></td>
  </tr>
  <tr><td><b>Area:</b></td>
    <td><asp:TextBox id="txtArea" Width="75px"
                     runat="server"></asp:TextBox></td>
  </tr>
</table>
</div>
</form>
</body>
</html>

Here is an example of running the program:

Object - The Ancestor to all Classes

Object - The Ancestor to all Classes

Although the Square class doesn't indicate that it is inheriting from any class, by virtue of belonging to a Visual Basic application, it inherits from Object. For this reason, the above code could also have been written as follows:

<script runat="server">
    Public Class Square
        Inherits Object

    End Class
</script>

This would produce the same results. Most of the time, if not always, you don't need to derive a class from Object: this inheritance is automatic and it is implied. By itself, the Object class provides some useful functionality to its children.

All of the methods of the Object class are public, making them directly available to the descendant classes. For most of them, if you want to use them, you should implement new versions of them in your class.

String Conversion

One of the functionalities provided by the Object class is the ability to convert any object to a string. Because this can mean different things to different classes. The Object class provides a method named ToString. Its syntax is:

Public Overridable Function ToString() As String

In some cases, you can directly call this method as it is available to your class already. Otherwise, most of the time, you will need to indicate how this method should be interpreted by your class, which is done by overriding it. To override this method, follow the rules of overriding a method by associating the Overrides keyword with the syntax of the method. In the body of the method, implement it as you see fit.

Because the Object.ToString() method returns a String object, you can assign its result to a string or pass it to a function or method that takes a string as argument.

Object and Classes Comparisons

Another valuable method of the Object class is called Equals. This method is used to compare two instances of a class for equality. This method is overloaded with two versions and each returns a Boolean value.

One of the versions of the Object.Equals() method has the following syntax:

Overloads Public Overridable Function Equals(ByVal obj As Object) As Boolean

This method can be called by any class of a .NET Framework application and it takes as argument an instance of the class that the called class needs to be compared to. The second version of the Object.Equals() method has the following syntax:

Overloads Public Shared Function Equals(ByVal objA As Object,_
					ByVal objB As Object) As Boolean

This version is declared as Shared. This means that it is not called by a specific instance of a class. Instead, it takes two arguments that each represents an instance of the classes that need to be compared.

 

Previous Copyright © 2016, FunctionX Next