|
Int |
|
Interfaces Fundamentals
Introduction
Creating an Interface
The basic formula to create an interface is:
[ access-modifier(s) ] [ Shadows ] Interface name
members
End Interface
You:
This would produce:
<script runat="server">
Interface IPolygon
End Interface
</script>
Here is an example:
OuterXml
New. Here is an example:
let
xaItemNumber
:
Affiche
Notice that, in both cases, the newly added element is empty.
As you might have realized, it is very easy to create an element. This is done in two simple steps:
<road />
Introduction
As.
This time, the result is:
Shadows keyword if necessary.Public, Protected, Overrides, MustOverride, and Overridable.
:
When implementing the method in a class, use the following formula;
This would produce:
When implementing the function in the body of the class, make sure you return the propriate type of value. Here is an example:
For Each XmlNodeList XmlNode ChildNodes. Here is an example:
as follows:
)
Here is an example:
AppendChild(). Here is an example:
This would produce:
This would produce:
Item:
. Here are examples:
.Item(3)
Based on the videos.xml file we had earlier, this would produce:
This would produce:
This would produce:
This would produce:
This would produce:
Here is an example of calling the method:
lvwRoads.ItemSelectionChanged.Add lvwRoadsItemSelectionChanged
This would produce:
This would produce:
xnRoad.FirstChild.NextSibling.NextSibling.InnerText |> ignore // Distance
xnRoad.FirstChild.NextSibling.NextSibling.NextSibling
This would produce:
As. Here
is an example:
.FirstChild
This would produce:
This would produce:
This would produce:
A Property in an Interface
An interface can contain one or more properties. If a property is intended to be read-write, the formula to create it is:
Property property-name As data-type
for child in xnlVideos do
child
This would produce:
When implementing the property in a class, end its first line with Implements, a period, and the name of the property. Here is an example:
<%@ Page Language="VB" %>
<!DOCTYPE html>
<script runat="server">
Public Interface IPolygon
Property Side As Double
End Interface
Public Class Triangle
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side() As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
End Class
</script>
<html>
<head runat="server">
<title>Geometry - Polygons: The Equilateral Triangle</title>
</head>
<body>
<h5>Geometry - Polygons: The Equilateral Triangle</h5>
<%
Dim length As Double = 248.97
Dim equilateral As Triangle
equilateral = New Triangle(length)
Response.Write("<p>Side: " & equilateral.Side & "</p>")
%>
</body>
</html>
This would produce:
If the property is intended to be read-only, the formula to create it is:
ReadOnly Property name Get
Notice that you must start with the ReadOnly keyword and end with Get. When implementing the property, at the end of the first line, omit Get to use it in the body of the property. Here are two examples:
<%@ Page Language="VB" %>
<!DOCTYPE html>
<script runat="server">
Public Interface IPolygon
Property Side As Double
ReadOnly Property Perimeter As Double
ReadOnly Property Area As Double
End Interface
Public Class Triangle
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side() As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
Public ReadOnly Property Perimeter() As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 3.0
End Get
End Property
Public ReadOnly Property Area() As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side * Math.Sqrt(3.0) / 4.0
End Get
End Property
End Class
Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
Dim Area = 0.0
Dim side = 0.0
Dim perimeter = 0.0
Dim equilateral As Triangle
If Not String.IsNullOrEmpty(txtSide.Text) Then
side = CDbl(txtSide.Text)
End If
equilateral = New Triangle(side)
txtArea.Text = equilateral.Area
txtPerimeter.Text = equilateral.Perimeter
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 - Polygons: The Equilateral Triangle</title>
</head>
<body>
<p id="main-title">Geometry - Polygons: The Equilateral Triangle</p>
<form id="frmGeometry" runat="server">
<div id="whole">
<table>
<tr>
<td>Side:</td>
<td><asp:TextBox id="txtSide" Width="75px" runat="server" /></td>
</tr>
<tr>
<td> </td>
<td><asp:Button id="btnCalculate" runat="server"
Text="Calculate" Width="85px"
OnClick="BtnCalculateClick" />
</td>
</tr>
<tr>
<td>Perimeter:</td>
<td><asp:TextBox id="txtPerimeter" 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:
Here is an example of using the webpage:
Here is an example of using the webpage:
If the property is intended to be write-only, the formula to create it is:
WriteOnly Property name Set
Other than that, you can create as many classes as you want and that implement an interface of your choice. Here is an example:
<%@ Page Language="VB" %>
<!DOCTYPE html>
<script runat="server">
Public Interface IPolygon
Property Side As Double
ReadOnly Property Perimeter As Double
ReadOnly Property Area As Double
End Interface
Public Class Hexagon
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side() As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
ReadOnly Property Perimeter() As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 6.0
End Get
End Property
ReadOnly Property Area() As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side * Math.Sqrt(3.0) * 3.0 / 2.0
End Get
End Property
End Class
Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
Dim side = 0.0
Dim Area = 0.0
Dim perimeter = 0.0
Dim figure As Hexagon
If Not String.IsNullOrEmpty(txtSide.Text) Then
side = CDbl(txtSide.Text)
End If
figure = New Hexagon(side)
txtArea.Text = figure.Area
txtPerimeter.Text = figure.Perimeter
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 - Polygons: The Hexagon</title>
</head>
<body>
<p id="main-title">Geometry - Polygons: The Hexagon</p>
<form id="frmGeometry" runat="server">
<div id="whole">
<table>
<tr>
<td>Side:</td>
<td><asp:TextBox id="txtSide" Width="75px" runat="server" /></td>
</tr>
<tr>
<td> </td>
<td><asp:Button id="btnCalculate" runat="server"
Text="Calculate" Width="85px"
OnClick="BtnCalculateClick" />
</td>
</tr>
<tr>
<td>Perimeter:</td>
<td><asp:TextBox id="txtPerimeter" runat="server" /></td>
</tr>
<tr>
<td>Area:</td>
<td><asp:TextBox id="txtArea" runat="server" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
Consider the following XML file named videos.xml:
Locating an Element Using its Index
Here is an example of using the webpage:
You can also add new members to the classes, members that are not related to the interface. Here are examples:
<%@ Page Language="VB" %>
<!DOCTYPE html>
<html>
<head runat="server">
<script runat="server">
Interface IPolygon
Property Side As Double
ReadOnly Property Perimeter As Double
ReadOnly Property Area As Double
End Interface
Public Class Triangle
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
Public ReadOnly Property Height As Double
Get
Return Me.Edge * Math.Sqrt(3.0) / 2.0
End Get
End Property
Public ReadOnly Property Perimeter As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 3.0
End Get
End Property
ReadOnly Property Area As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side * Math.Sqrt(3.0) / 4.0
End Get
End Property
ReadOnly Property RadiusOfCircumscribedCircle As Double
Get
Return Me.Edge / Math.Sqrt(3.0)
End Get
End Property
' Also called Apothem
ReadOnly Property RadiusOfInscribedCircle As Double
Get
Return Me.Edge * Math.Sqrt(3.0) / 6.0
End Get
End Property
End Class
Public Class Square
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
Public ReadOnly Property Diagonal As Double
Get
Return Me.Side * Math.Sqrt(2.0)
End Get
End Property
ReadOnly Property Perimeter As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 4.0
End Get
End Property
ReadOnly Property Area As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side
End Get
End Property
End Class
Public Class Pentagon
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
Public ReadOnly Property Height As Double
Get
Return Me.Edge * Math.Sqrt(5.0 + (2.0 * Math.Sqrt(5))) / 2.0
End Get
End Property
Public ReadOnly Property Diagonal As Double
Get
Return Me.Side * ((1 + Math.Sqrt(5.0)) / 2.0)
End Get
End Property
ReadOnly Property Perimeter As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 5.0
End Get
End Property
ReadOnly Property Area As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side * Math.Sqrt(5.0 * (5 + (2 * Math.Sqrt(5.0)))) / 4.0
End Get
End Property
End Class
Public Class Hexagon
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
ReadOnly Property Perimeter As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 6.0
End Get
End Property
ReadOnly Property Area As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side * Math.Sqrt(3.0) * 3.0 / 2.0
End Get
End Property
End Class
Public Class Octagon
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
ReadOnly Property Perimeter As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 8.0
End Get
End Property
ReadOnly Property Area As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side * 2.0 * (1 + Math.Sqrt(2.0))
End Get
End Property
End Class
Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
Dim side = 0.0
Dim equilateral As Triangle
If Not String.IsNullOrEmpty(txtSide.Text) Then
side = CDbl(txtSide.Text)
End If
equilateral = New Triangle(side)
txtHeight.Text = equilateral.Height
txtPerimeter.Text = equilateral.Perimeter
txtArea.Text = equilateral.Area
txtRadiusOfCircumscribedCircle.Text = equilateral.RadiusOfCircumscribedCircle
txtRadiusOfInscribedCircle.Text = equilateral.RadiusOfInscribedCircle
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: 305px;
}
</style>
<title>Geometry - Polygons: The Equilateral Triangle</title>
</head>
<body>
<p id="main-title">Geometry - Polygons: The Equilateral Triangle</p>
<form id="frmGeometry" runat="server">
<div id="whole">
<table>
<tr>
<td>Side:</td>
<td><asp:TextBox id="txtSide" Width="75px" runat="server" /></td>
</tr>
<tr>
<td> </td>
<td><asp:Button id="btnCalculate" runat="server"
Text="Calculate" Width="85px"
OnClick="BtnCalculateClick" />
</td>
</tr>
<tr>
<td>Height:</td>
<td><asp:TextBox id="txtHeight" runat="server" /></td>
</tr>
<tr>
<td>Perimeter:</td>
<td><asp:TextBox id="txtPerimeter" runat="server" /></td>
</tr>
<tr>
<td>Area:</td>
<td><asp:TextBox id="txtArea" runat="server" /></td>
</tr>
<tr>
<td>Radius of Circumscribed Circle:</td>
<td><asp:TextBox id="txtRadiusOfCircumscribedCircle" runat="server" /></td>
</tr>
<tr>
<td>Radius of Inscribed Circle:</td>
<td><asp:TextBox id="txtRadiusOfInscribedCircle" runat="server" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
Here is an example of using the webpage:
Primary Options on Using an Interface
Declaring a Variable of Interface Type
You cannot declare a variable of an interface and use it directly as you would a class. On the othe hand, you can declare a variable by using the name of the interface but not allocate memory for the variable. Here is an example:
<%@ Page Language="VB" %>
<!DOCTYPE html>
<html>
<head runat="server">
<script runat="server">
Interface IPolygon
Property Side As Double
ReadOnly Property Perimeter As Double
ReadOnly Property Area As Double
End Interface
</script>
<title>Geometry - Polygons</title>
</head>
<body>
<%
Dim figure As IPolygon
%>
</body>
</html>
When allocating memory for the object using the New operator, you must use a class that implements that interface. After that, you can use the object. Here is an example:
<%@ Page Language="VB" %>
<!DOCTYPE html>
<html>
<head runat="server">
<script runat="server">
Interface IPolygon
Property Side As Double
ReadOnly Property Perimeter As Double
ReadOnly Property Area As Double
End Interface
Public Class Square
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
Public ReadOnly Property Diagonal As Double
Get
Return Me.Side * Math.Sqrt(2.00)
End Get
End Property
ReadOnly Property Perimeter As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 4.0
End Get
End Property
ReadOnly Property Area As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side
End Get
End Property
End Class
Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
Dim side = 0.0
Dim plate As IPolygon
If Not String.IsNullOrEmpty(txtSide.Text) Then
side = CDbl(txtSide.Text)
End If
plate = New Square(side)
txtPerimeter.Text = plate.Perimeter
txtArea.Text = plate.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: 305px;
}
</style>
<title>Geometry - Polygons: The Square</title>
</head>
<body>
<p id="main-title">Geometry - Polygons: The Square</p>
<form id="frmGeometry" runat="server">
<div id="whole">
<table>
<tr>
<td>Side:</td>
<td><asp:TextBox id="txtSide" Width="75px" runat="server" /></td>
</tr>
<tr>
<td> </td>
<td><asp:Button id="btnCalculate" runat="server"
Text="Calculate" Width="85px"
OnClick="BtnCalculateClick" />
</td>
</tr>
<tr>
<td>Perimeter:</td>
<td><asp:TextBox id="txtPerimeter" runat="server" /></td>
</tr>
<tr>
<td>Area:</td>
<td><asp:TextBox id="txtArea" runat="server" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
You can also declare the variable and allocate its memory on the same line. Here is an example:
<script runat="server">
. . .
Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
Dim side = 0.0
If Not String.IsNullOrEmpty(txtSide.Text) Then
side = CDbl(txtSide.Text)
End If
Dim plate As IPolygon = New Square(side)
txtPerimeter.Text = plate.Perimeter
txtArea.Text = plate.Area
End Sub
</script>
If you use any of these two techniques, you can access only the members of the interface. The non-interface members of the class would not be available. As a result, the following will produce an error:
<%@ Page Language="VB" %>
<!DOCTYPE html>
<html>
<head runat="server">
<script runat="server">
Interface IPolygon
Property Side As Double
ReadOnly Property Perimeter As Double
ReadOnly Property Area As Double
End Interface
Public Class Square
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
Public ReadOnly Property Diagonal As Double
Get
Return Me.Side * Math.Sqrt(2.00)
End Get
End Property
ReadOnly Property Perimeter As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 4.0
End Get
End Property
ReadOnly Property Area As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side
End Get
End Property
End Class
Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
Dim side = 0.0
If Not String.IsNullOrEmpty(txtSide.Text) Then
side = CDbl(txtSide.Text)
End If
Dim plate As IPolygon = New Square(side)
txtPerimeter.Text = plate.Perimeter
txtArea.Text = plate.Area
' Since the Diagonal is not a member of the interface, the variable
' (declared from the interface) cannot access it
txtDiagonal.Text = plate.Diagonal
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: 305px;
}
</style>
<title>Geometry - Polygons: The Square</title>
</head>
<body>
<p id="main-title">Geometry - Polygons: The Square</p>
<form id="frmGeometry" runat="server">
<div id="whole">
<table>
<tr>
<td>Side:</td>
<td><asp:TextBox id="txtSide" Width="75px" runat="server" /></td>
</tr>
<tr>
<td> </td>
<td><asp:Button id="btnCalculate" runat="server"
Text="Calculate" Width="85px"
OnClick="BtnCalculateClick" />
</td>
</tr>
<tr>
<td>Diagonal:</td>
<td><asp:TextBox id="txtDiagonal" runat="server" /></td>
</tr>
<tr>
<td>Perimeter:</td>
<td><asp:TextBox id="txtPerimeter" runat="server" /></td>
</tr>
<tr>
<td>Area:</td>
<td><asp:TextBox id="txtArea" runat="server" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
Passing an Interface As Argument
If you are defining a procedure, a function, or a method that receives an argument and the argument is an object of a class that either inherits from another class or implements an interface, in some cases, you can pass either its parent class or the interface it implements. In the body of the procedure, you can access the members of the interface. Here is an example:
<%@ Page Language="VB" %>
<!DOCTYPE html>
<html>
<head runat="server">
<script runat="server">
Interface IPolygon
Property Side As Double
ReadOnly Property Perimeter As Double
ReadOnly Property Area As Double
End Interface
Public Class Pentagon
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
ReadOnly Property Perimeter As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 5.0
End Get
End Property
ReadOnly Property Area As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side * Math.Sqrt(5.00 * (5.00 + (2.00 * Math.Sqrt(5.00)))) / 4.00
End Get
End Property
End Class
Sub Present(ByVal figure As IPolygon)
txtPerimeter.Text = figure.Perimeter
txtArea.Text = figure.Area
End Sub
Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
Dim side = 0.0
Dim pol As IPolygon
If Not String.IsNullOrEmpty(txtSide.Text) Then
side = CDbl(txtSide.Text)
End If
pol = New Pentagon(side)
Present(pol)
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: 305px;
}
</style>
<title>Geometry - Polygons: The Pentagon</title>
</head>
<body>
<p id="main-title">Geometry - Polygons: The Pentagon</p>
<form id="frmGeometry" runat="server">
<div id="whole">
<table>
<tr>
<td>Side:</td>
<td><asp:TextBox id="txtSide" Width="75px" runat="server" /></td>
</tr>
<tr>
<td> </td>
<td><asp:Button id="btnCalculate" runat="server"
Text="Calculate" Width="85px"
OnClick="BtnCalculateClick" />
</td>
</tr>
<tr>
<td>Perimeter:</td>
<td><asp:TextBox id="txtPerimeter" runat="server" /></td>
</tr>
<tr>
<td>Area:</td>
<td><asp:TextBox id="txtArea" runat="server" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
Keep in mind that you can access only the members of the interface.
Returning an Interface
A function or a method can return an object based on an interface. When creating the function or method, specify its return type as the desired interface. Here is an example:
<script runat="server">
Interface IPolygon
Property Side As Double
ReadOnly Property Perimeter As Double
ReadOnly Property Area As Double
End Interface
Function Create() As IPolygon
End Function
</script>
Remember that you cannot simply instantiate an interface and directly use it as you would an object of a class. As a result, you cannot directly return an object based on an interface. Instead, you can declare a variable of a class that implements the interface and return that variable. In the code section where you need to use the object, you can get the value returned by the function and use it. Here is an example:
<%@ Page Language="VB" %>
<!DOCTYPE html>
<html>
<head runat="server">
<script runat="server">
Interface IPolygon
Property Side As Double
ReadOnly Property Perimeter As Double
ReadOnly Property Area As Double
End Interface
Public Class Pentagon
Implements IPolygon
Protected Edge As Double
Public Sub New(ByVal side As Double)
Me.Edge = side
End Sub
Public Property Side As Double Implements IPolygon.Side
Get
Return Me.Edge
End Get
Set(ByVal value As Double)
Me.Edge = value
End Set
End Property
Public ReadOnly Property Diagonal As Double
Get
Return Me.Side * ((1.00 * Math.Sqrt(5.00)) / 2.00)
End Get
End Property
ReadOnly Property Perimeter As Double Implements IPolygon.Perimeter
Get
Return Me.Side * 5.0
End Get
End Property
ReadOnly Property Area As Double Implements IPolygon.Area
Get
Return Me.Side * Me.Side * Math.Sqrt(5.00 * (5.00 + (2.00 * Math.Sqrt(5.00)))) / 4.00
End Get
End Property
End Class
Sub Present(ByVal figure As IPolygon)
txtPerimeter.Text = figure.Perimeter
txtArea.Text = figure.Area
End Sub
Function Create() As IPolygon
Dim side As Double = 0.0
Dim pol As IPolygon
If Not String.IsNullOrEmpty(txtSide.Text) Then
side = CDbl(txtSide.Text)
End If
pol = New Pentagon(side)
Return pol
End Function
Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
Dim shape As Pentagon
shape = Create()
Present(shape)
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: 305px;
}
</style>
<title>Geometry - Polygons: The Pentagon</title>
</head>
<body>
<p id="main-title">Geometry - Polygons: The Pentagon</p>
<form id="frmGeometry" runat="server">
<div id="whole">
<table>
<tr>
<td>Side:</td>
<td><asp:TextBox id="txtSide" Width="75px" runat="server" /></td>
</tr>
<tr>
<td> </td>
<td><asp:Button id="btnCalculate" runat="server"
Text="Calculate" Width="85px"
OnClick="BtnCalculateClick" />
</td>
</tr>
<tr>
<td>Perimeter:</td>
<td><asp:TextBox id="txtPerimeter" runat="server" /></td>
</tr>
<tr>
<td>Area:</td>
<td><asp:TextBox id="txtArea" runat="server" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
In reality, the function must return an object based on either the interface itself or of a class that implements the interface.
Options on Creating, Implementing, and Using Interfaces
Inheriting an Interface
An interface can be derived from another interface but an interface cannot derive from a class. To create an interface based on another interface, use the Inherits keyword. A member of the parent interface cannot be defined in a derived interface.
The derived interface is supposed to add some behavior using methods and/or properties. In any class that needs the behaviors of the new interface, you must implement all members of the new interface and its parents. Here is an example:
open System
open System.Windows.Forms
type WorkingStatus =
| New
| Used
| NeedsRepair
type IProduct =
abstract StockNumber : int with get, set
abstract ItemName : string with get, set
abstract UnitPrice : float with get, set
type ISalesTax =
inherit IProduct
abstract TaxRate : float with get, set
abstract TaxAmount : float with get
type BoatPurchase(number, name, price, tRate) =
let nbr = ref number
let nm = ref name
let cost = ref price
let tr = ref tRate
interface ISalesTax with
member this.StockNumber with get() = !nbr and set(value) = nbr := value
member this.ItemName with get() = !nm and set(value) = nm := value
member this.UnitPrice with get() = !cost and set(value) = cost := value
member this.TaxRate with get() = !tr and set(value) = tr := value
member this.TaxAmount with get() = !cost * !tr / 100.00
member this.MarkedPrice with get() = !cost + (this :> ISalesTax).TaxAmount
member this.StockNumber with get() = (this :> ISalesTax).StockNumber
member this.ItemName with get() = (this :> ISalesTax).ItemName
member this.UnitPrice with get() = (this :> ISalesTax).UnitPrice
let rndNumber = new Random()
let strStockNumber = string (rndNumber.Next(100, 999)) + "-" + string (rndNumber.Next(100, 999))
let item = BoatPurchase((rndNumber.Next(10000, 90000)), "Self-Propelled Gas Mower with Auto Choke", 399.95, 7.75)
let salesTax = (item :> ISalesTax).TaxAmount
// Form: Water Runner
let waterRunner = new Form(Width = 388, Height = 238, Text = "Water Runner")
// Label: Stock Number
waterRunner.Controls.Add(new Label(Left = 17, Top = 22, Width = 75, Text = "Stock #:"))
// Text Box: Stock Number
let txtStockNumber = new TextBox(Left = 113, Top = 19, Width = 78)
waterRunner.Controls.Add txtStockNumber
// Label: Status
waterRunner.Controls.Add(new Label(Left = 205, Top = 21, Width = 54, Text = "Status:"))
// Combo Box: Status
let cbxStatus = new ComboBox(Left = 275, Top = 19, Width = 90, Text = "New")
cbxStatus.Items.AddRange([| "New"; "Used"; "Needs Repair" |])
waterRunner.Controls.Add cbxStatus
// Label: Boat Model
waterRunner.Controls.Add(new Label(Left = 17, Top = 51, Width = 75, Text = "Boat Model:"))
// Text Box: Model
let txtBoatModel = new TextBox(Left = 113, Top = 48, Width = 250)
waterRunner.Controls.Add txtBoatModel
// Label: Seating Capacity
waterRunner.Controls.Add(new Label(Left = 17, Top = 79, Width = 95, Text = "Seating Capacity:"))
// Text Box: Seating Capacity
let txtSeatingCapacity = new TextBox(Left = 113, Top = 77, Width = 75, Text = "1")
waterRunner.Controls.Add txtSeatingCapacity
// Label: Retail Price
waterRunner.Controls.Add(new Label(Left = 205, Top = 80, Width = 68, Text = "Retail Price:"))
// Text Box: Retail Price
let txtRetailPrice = new TextBox(Left = 275, Top = 77, Width = 90, Text = "0.00")
waterRunner.Controls.Add txtRetailPrice
// Label: Tax Rate
waterRunner.Controls.Add(new Label(Left = 18, Top = 106, Width = 78, Text = "Tax Rate:"))
// Text Box: Tax Rate
let txtTaxRate = new TextBox(Left = 114, Top = 106, Width = 60, Text = "7.75")
waterRunner.Controls.Add txtTaxRate
// Label: %
waterRunner.Controls.Add(new Label(Left = 175, Top = 109, Width = 14, Text = "%"))
// Label: Tax Amount
waterRunner.Controls.Add(new Label(Left = 17, Top = 138, Width = 85, Text = "Tax Amount:"))
// Text Box: Tax Amount
let txtTaxAmount = new TextBox(Left = 113, Top = 135, Width = 75, Text = "0.00")
waterRunner.Controls.Add txtTaxAmount
// Label: Sale Price
waterRunner.Controls.Add(new Label(Left = 205, Top = 138, Width = 62, Text = "Sale Price:"))
// Text Box: Sale Price
let txtSalePrice = new TextBox(Left = 275, Top = 135, Width = 90, Text = "0.00")
waterRunner.Controls.Add txtSalePrice
// Button: Calculate
let btnCalculate = new Button(Left = 275, Top = 106, Width = 90, Text = "Calculate")
let btnCalculateClick e =
let boat = new BoatPurchase(int txtStockNumber.Text, txtBoatModel.Text, float txtRetailPrice.Text, float txtTaxRate.Text)
let strTax = sprintf "%0.02f" (boat :> ISalesTax).TaxAmount
let strSalePrice = sprintf "%0.02f" boat.MarkedPrice
txtTaxAmount.Text <- strTax
txtSalePrice.Text <- strSalePrice
btnCalculate.Click.Add btnCalculateClick
waterRunner.Controls.Add btnCalculate
// Button: Close
let btnClose = new Button(Left = 275, Top = 174, Width = 90, Text = "Close")
let btnCloseClick e = waterRunner.Close()
btnClose.Click.Add btnCloseClick
waterRunner.Controls.Add btnClose
do Application.Run waterRunner
In the same way, an interface can inherit from as many interfaces as necessary.
Implementing Many Interfaces
F# doesn't support multiple inheritance, which is the ability to create a class that is
directly based on many classes. As an alternative, you can create a class that implements more than one
interface.
The formula to implement many interfaces is:
type Class-Name[(Parametere(s))] =
Member(s)
interface InterfaceName 1 with
Interface-Member(s) 1
interface InterfaceName 2 with
Interface-Member(s) 2
. . .
interface InterfaceName n with
Interface-Member(s) n
In the body of the class, each interface has its implementation section. The individual
implementations follow the techniques we have used so far. To access the member of an interface from the object
created using the class, you can declare a variable that is up-cast from the interface. This can be done as follows:
open System
open System.Windows.Forms
type IProduct =
abstract ItemNumber : int with get, set
abstract ItemName : string with get, set
abstract UnitPrice : float with get, set
type IDiscount =
abstract DiscountRate : float with get, set
abstract DiscountAmount : float with get
type StoreItem(number, make, category, subcat, name, size, price, discrate) =
let nbr = ref number
let mutable mk = make
let mutable cat = category
let mutable sub = subcat
let nm = ref name
let mutable sz = size
let prc = ref price
let dr = ref discrate
interface IProduct with
member this.ItemNumber with get() = !nbr and set(value) = nbr := value
member this.ItemName with get() = !nm and set(value) = nm := value
member this.UnitPrice with get() = !prc and set(value) = prc := value
interface IDiscount with
member this.DiscountRate with get() = !dr and set(value) = dr := value
member this.DiscountAmount with get() = !prc * !dr / 100.00
member this.Manufacturer with get() = mk and set(value) = mk <- value
member this.Category with get() = cat and set(value) = cat <- value
member this.SubCategory with get() = sub and set(value) = sub <- value
member this.ItemSize with get() = sz and set(value) = sz <- value
member this.MarkedPrice with get() = this.UnitPrice - (this :> IDiscount).DiscountAmount
new() = StoreItem(0, "", "", "", "", "", 0.00, 0.00)
new(number, make, category, subcategory, name, size, price) = StoreItem(number, make, category, subcategory, name, size, price, 0.00)
override this.GetHashCode() = this.GetHashCode()
override this.Equals(obj) =
match obj with
| :? StoreItem as si -> this.ItemNumber = si.ItemNumber
| _ -> false
override this.ToString() =
"Item #: " + string this.ItemNumber + ", " + this.Manufacturer + ", " + this.Category + " " + this.SubCategory + ", Named " + this.ItemName + "(" + this.ItemSize + "), Price: " + string this.UnitPrice
interface IComparable with
member this.CompareTo(obj : Object) : int =
match obj with
| :? StoreItem as si -> compare this.ItemName si.ItemName
| _ -> 0
member this.ItemNumber with get() = (this :> IProduct).ItemNumber
member this.ItemName with get() = (this :> IProduct).ItemName
member this.UnitPrice with get() = (this :> IProduct).UnitPrice
member this.DiscountRate with get() = (this :> IDiscount).DiscountRate
member this.DiscountAmount with get() = (this :> IDiscount).DiscountAmount
let rndNumber = new Random()
let si = new StoreItem(rndNumber.Next(100001, 999999), "Guess", "Women", "Dresses", "Zip Front Fit and Flare Dressr", "4", 135.75, float 25)
// Form: Department Store
let departmentStore = new Form(Width = 390, Height = 238, Text = "Department Store")
// Label: Item Number
departmentStore.Controls.Add(new Label(Left = 22, Top = 18, Width = 74, Text = "Item #:"))
// Text Box: Item Number
let txtItemNumber = new TextBox(Left = 101, Top = 15, Width = 64)
txtItemNumber.Text <- string si.ItemNumber
departmentStore.Controls.Add txtItemNumber
// Label: Manufacturer
departmentStore.Controls.Add(new Label(Left = 22, Top = 44, Width = 74, Text = "Manufacturer:"))
// Text Box: Manufacturer
let txtManufacturer = new TextBox(Left = 101, Top = 41, Width = 262)
txtManufacturer.Text <- si.Manufacturer
departmentStore.Controls.Add txtManufacturer
// Label: Category
departmentStore.Controls.Add(new Label(Left = 22, Top = 70, Width = 52, Text = "Category:"))
// Text Box: Category
let txtCategory = new TextBox(Left = 101, Top = 67, Width = 87)
txtCategory.Text <- si.Category
departmentStore.Controls.Add txtCategory
// Label: Sub-Category
let lblSubCategory = new Label(Left = 194, Top = 70, Width = 78, Text = "Sub-Category:")
departmentStore.Controls.Add lblSubCategory
// Text Box: Sub-Category
let txtSubCategory = new TextBox(Left = 274, Top = 67, Width = 90)
txtSubCategory.Text <- si.SubCategory
departmentStore.Controls.Add txtSubCategory
// Label: Item Name
departmentStore.Controls.Add(new Label(Left = 22, Top = 96, Width = 68, Text = "Item Name:"))
// Text Box: Item Name
let txtItemName = new TextBox(Left = 101, Top = 93, Width = 262)
txtItemName.Text <- si.ItemName
departmentStore.Controls.Add txtItemName
// Label: Item Size
departmentStore.Controls.Add(new Label(Left = 22, Top = 122, Width = 64, Text = "Item Size:"))
// Text Box: Item Size
let txtItemSize = new TextBox(Left = 101, Top = 119, Width = 87)
txtItemSize.Text <- si.ItemSize
departmentStore.Controls.Add txtItemSize
// Label: Unit Price
departmentStore.Controls.Add(new Label(Left = 194, Top = 122, Width = 75, Text = "Unit Price:"))
// Text Box: Unit Price
let txtUnitPrice = new TextBox(Left = 288, Top = 119, Width = 75)
txtUnitPrice.Text <- sprintf "%g" si.UnitPrice
departmentStore.Controls.Add txtUnitPrice
// Label: Discount Rate
let lblDiscountRate = new Label(Left = 22, Top = 148, Width = 78, Text = "Discount Rate:")
departmentStore.Controls.Add lblDiscountRate
// Text Box: Discount Rate
let txtDiscountRate = new TextBox(Left = 101, Top = 145, Width = 87)
txtDiscountRate.Text <- (sprintf "%g%c" si.DiscountRate '%')
departmentStore.Controls.Add txtDiscountRate
// Label: Discount Amount
let lblDiscountAmount = new Label(Left = 194, Top = 148, Width = 94, Text = "Discount Amount:")
departmentStore.Controls.Add lblDiscountAmount
// Text Box: Discount Amount
let txtDiscountAmount = new TextBox(Left = 288, Top = 145, Width = 75)
txtDiscountAmount.Text <- sprintf "%0.02f" si.DiscountAmount
departmentStore.Controls.Add txtDiscountAmount
// Label: Marked Price
departmentStore.Controls.Add(new Label(Left = 22, Top = 174, Width = 77, Text = "Marked Price:"))
// Text Box: MarkedPrice
let txtMarkedPrice = new TextBox(Left = 101, Top = 171, Width = 87)
txtMarkedPrice.Text <- sprintf "%0.02f" si.MarkedPrice
departmentStore.Controls.Add txtMarkedPrice
// Button: Close
let btnClose = new Button(Left = 288, Top = 174, Text = "Close")
let btnCloseClick e = departmentStore.Close()
btnClose.Click.Add btnCloseClick
departmentStore.Controls.Add btnClose
do Application.Run departmentStore
Multiple Derivations
As we know already, you can create a class that is based on another class, and you can create a class that implements an interface.
You are not allowed to create a class that is directly based on more than one class. Instead you can either use transitive inheritance, in which case one class is based on another class that itself is based on another class. Or you can create a class that implements many interfaces. That, you can create a class that implements more than one interface. In the body of the class, create a section for each interface and implement all its members. Here is an example:
open System
type IProduct =
abstract ItemNumber : string with get, set
abstract ItemName : string with get, set
abstract UnitPrice : float with get, set
type ISalesTax =
abstract TaxRate : float with get, set
abstract TaxAmount : float with get
type VehiclePurchase(number, name, price, tRate) =
let nbr = ref number
let nm = ref name
let cost = ref price
let tr = ref tRate
interface IProduct with
member this.ItemNumber with get() = !nbr and set(value) = nbr := value
member this.ItemName with get() = !nm and set(value) = nm := value
member this.UnitPrice with get() = !cost and set(value) = cost := value
interface ISalesTax with
member this.TaxRate with get() = !tr and set(value) = tr := value
member this.TaxAmount with get() = !cost * !tr / 100.00
member this.MarkedPrice with get() = !cost + (this :> ISalesTax).TaxAmount
member this.ItemNumber with get() = (this :> IProduct).ItemNumber
member this.ItemName with get() = (this :> IProduct).ItemName
member this.UnitPrice with get() = (this :> IProduct).UnitPrice
//member this.TaxRate with get() = (this :> ISalesTax).TaxRate
//member this.TaxAmount with get() = (this :> ISalesTax).TaxAmount
let rndNumber = new Random()
let strItemNumber = string (rndNumber.Next(100, 999)) + "-" + string (rndNumber.Next(100, 999)) + "-" + string (rndNumber.Next(100, 999))
let registrationFee = 128.00
let downPayment = 3000.00
let item = VehiclePurchase(strItemNumber, "Toyota Camry (2010)", 18750.00 - downPayment + registrationFee, 7.75)
let salesTax = (item :> ISalesTax).TaxAmount
-------------------------------------------------------------------------
An Interface Derived
Like a regular class, an interface can be derived from
another interface but an interface cannot derive from a class. To create
an interface based on another, use the Inherits keyword. As mentioned for the interfaces, you can use the
parent interface to list the members that the deriving classes would
implement. Still remember that since an interface cannot implement a
member, the member of the parent interface cannot be defined in a derived
interface. This implement would wait for the actual class(es) that would
be based on the child (or even the parent) interface. Here is an example:
File: RegularTriangle.vb
Public Interface IGeometricShape
ReadOnly Property Type() As String
End Interface
Public Interface ITriangle
Inherits IGeometricShape
ReadOnly Property Name() As String
Property Base() As Double
Property Height() As Double
Function CalculatePerimeter() As Double
Function CalculateArea() As Double
End Interface
After deriving a class from an interface, when
defining the class, you must implement the member of the immediate
interface and those of the ancestor interface(s). Here is an example:
File: RegularTriangle.vb
Public Interface IGeometricShape
ReadOnly Property Type() As String
End Interface
Public Interface ITriangle
Inherits IGeometricShape
ReadOnly Property Name() As String
Property Base() As Double
Property Height() As Double
Function CalculatePerimeter() As Double
Function CalculateArea() As Double
End Interface
Public Class RegularTriangle
Implements ITriangle
Public bas As Double
Public hgt As Double
Public sd1 As Double
Public sd2 As Double
Public ReadOnly Property Type() As String Implements ITriangle.type
Get
Return "Triangle"
End Get
End Property
' Default constructor: the user will specify the dimensions
Public Sub New()
bas = 0
hgt = 0
sd1 = 0
sd2 = 0
End Sub
' A triangle based on known base and height
Public Sub New(ByVal b As Double, ByVal h As Double)
bas = b
hgt = h
End Sub
' A triangle based on the measurements of the sides
Public Sub New(ByVal b As Double, ByVal side1 As Double, ByVal side2 As Double)
bas = b
sd1 = side1
sd2 = side2
End Sub
' A triangle whose all sides and the height are known
Public Sub New(ByVal b As Double, ByVal h As Double, _
ByVal side1 As Double, ByVal side2 As Double)
bas = b
hgt = h
sd1 = side1
sd2 = side2
End Sub
Public Property Base() As Double Implements ITriangle.Base
Get
Return bas
End Get
Set(ByVal Value As Double)
If bas < 0 Then
bas = 0
Else
bas = Value
End If
End Set
End Property
Public Function CalculateArea() As Double Implements ITriangle.CalculateArea
Return bas * hgt / 2
End Function
Public Function CalculatePerimeter() As Double Implements _
ITriangle.CalculatePerimeter
Return bas + sd1 + sd2
End Function
Public Property Height() As Double Implements ITriangle.Height
Get
Return hgt
End Get
Set(ByVal Value As Double)
If hgt < 0 Then
hgt = 0
Else
hgt = Value
End If
End Set
End Property
Public ReadOnly Property Name() As String Implements ITriangle.Name
Get
Return "Regular"
End Get
End Property
End Class
Here is an example of testing the class:
File: Exercise.vb
Module Exercise
Public Function Main() As Integer
Dim reg As RegularTriangle = New RegularTriangle(35.28, 26.44)
Console.WriteLine("Shape Type: {0}", reg.Type)
Console.WriteLine("Triangle Type: {0}", reg.Name)
Console.WriteLine("=-= Characteristics =-=")
Console.WriteLine("Base: {0}", reg.Base)
Console.WriteLine("Height: {0}", reg.Height)
Console.WriteLine("Area: {0}", reg.CalculateArea)
Return 0
End Function
End Module
This would produce:
Shape Type: Triangle
Triangle Type: Regular
=-= Characteristics =-=
Base: 35.28
Height: 26.44
Area: 466.4016
Multiple Inheritance
Multiple inheritance consists of creating a class that
is based on more than one parent. In the Microsoft Visual Basic language
(in fact in the .NET Framework), you cannot derive a class from more than
one class. This functionality is available only with interfaces.
To create a class based on more than one interface,
after the Implements keyword, enter the name of each interface and
separate them with commas. Here is an example:
Public Interface IGeometricShape
ReadOnly Property Type() As String
End Interface
Public Interface ICalculation
End Interface
Public Interface ITriangle
Inherits IGeometricShape, ICalculation
End Interface
The same rules apply for multiple inheritance: you
must implements all members of each parent interface.
Besides deriving from an interface, you can also
create a class that is based on a class and one or more interfaces. To do
this, under the line that specifies the name of the class, use the Inherits
keyword to specify the name of the parent, press Enter, and use the Implements
keyword to specify the name of the class that serves as the parent
interface. Here is an example:
Introduction
Therefore, when implementing the ICloneable interface, in
your class, you can simply call
the MemberwiseClone() method.
Comparing Two Objects
Comparing two objects consists of finding out which one
comes before. The comparison is simple if you are dealing with values of
primitive types. For example, it is easy to know that 2 is lower than 5, but it
is not obvious to compare two objects created from a composite type, such as two
students, two cars, or two food items.
To assist you with comparing two objects, the .NET Framework
provides various comparable interfaces. One of these interfaces is named
IComparable. The IComparable interface is a member of the System namespace. Obviously you must define
what would be compared and how the comparison would be carried. For example, to
compare two Student objects of the above class, you can ask the compiler to
base the comparison on the student number. Here is an example:
open System
open System.Windows.Forms
type StoreItem(number, make, category, subcategory, name, size, price, discrate) =
let mutable nbr = number
let mutable mk = make
let mutable cat = category
let mutable sub = subcategory
let mutable nm = name
let mutable sz = size
let mutable prc = price
let mutable rate = discrate
member this.ItemNumber with get() = nbr and set(value) = nbr <- value
member this.Manufacturer with get() = mk and set(value) = mk <- value
member this.Category with get() = cat and set(value) = cat <- value
member this.SubCategory with get() = sub and set(value) = sub <- value
member this.ItemName with get() = nm and set(value) = nm <- value
member this.ItemSize with get() = sz and set(value) = sz <- value
member this.UnitPrice with get() = prc and set(value) = prc <- value
member this.DiscountRate with get() = rate and set(value) = rate <- value
member this.DiscountAmount with get() = this.UnitPrice * this.DiscountRate / 100.00
member this.MarkedPrice with get() = this.UnitPrice - this.DiscountAmount
new() = StoreItem("", "", "", "", "", "", 0.00, 0.00)
new(number, make, category, subcategory, name, size, price) = StoreItem(number, make, category, subcategory, name, size, price, 0.00)
override this.Equals(obj) =
match obj with
| :? StoreItem as si -> this.ItemNumber = si.ItemNumber
| _ -> false
override this.ToString() =
"Item #: " + this.ItemNumber + ", " + this.Manufacturer + ", " + this.Category + " " + this.SubCategory + ", Named " + this.ItemName + "(" + this.ItemSize + "), Price: " + string this.UnitPrice
interface IComparable with
member this.CompareTo(obj : Object) : int =
match obj with
| :? StoreItem as si -> compare this.ItemName si.ItemName
| _ -> 0
let si1 = new StoreItem("279403", "Reef", "Men", "Sandals", "Men's Phantom Ultimate Flip Flop", "10", 45.50, float 0)
let si2 = new StoreItem("927497", "Guess", "Women", "Dresses", "Zip Front Fit and Flare Dressr", "4", 155.75, float 25)
let si3 = new StoreItem("293041", "Anne Klein", "Women", "Skirts", "A-Line Skirt with Lining", "4", 82.50, float 50)
let si4 = new StoreItem("537946", "Guess", "Women", "Dresses", "Zip Front Fit and Flare Dressr", "4", 155.75, float 25)
let comparison1 = sprintf "%i" ((si1 :> IComparable).CompareTo(si2))
let comparison2 = sprintf "%i" ((si1 :> IComparable).CompareTo(si3))
let comparison3 = sprintf "%i" ((si2 :> IComparable).CompareTo(si4))
// Form: Department Store
let departmentStore = new Form()
departmentStore.Width <- 520
departmentStore.Height <- 225
departmentStore.Text <- "Department Store"
// Label: Item 1
let lblItem1 = new Label()
lblItem1.Left <- 12
lblItem1.Top <- 18
lblItem1.Width <- 500
lblItem1.Text <- si1.ToString()
departmentStore.Controls.Add lblItem1
// Label: Item 3
let lblItem2 = new Label()
lblItem2.Left <- 12
lblItem2.Top <- 42
lblItem2.Width <- 500
lblItem2.Text <- si2.ToString()
departmentStore.Controls.Add lblItem2
// Label: Item 3
let lblItem3 = new Label()
lblItem3.Left <- 12
lblItem3.Top <- 64
lblItem3.Width <- 500
lblItem3.Text <- si3.ToString()
departmentStore.Controls.Add lblItem3
// Label: Item 4
let lblItem4 = new Label()
lblItem4.Left <- 12
lblItem4.Top <- 88
lblItem4.Width <- 500
lblItem4.Text <- si4.ToString()
departmentStore.Controls.Add lblItem4
// Label: Comparison 1
let lblComparison1 = new Label()
lblComparison1.Left <- 12
lblComparison1.Top <- 118
lblComparison1.Width <- 500
lblComparison1.Text <- "Item 927497 compared to 279403 produces: " + comparison1.ToString()
departmentStore.Controls.Add lblComparison1
// Label: Comparison 2
let lblComparison2 = new Label()
lblComparison2.Left <- 12
lblComparison2.Top <- 142
lblComparison2.Width <- 500
lblComparison2.Text <- "Item 927497 compared to 537946 produces: " + comparison2.ToString()
departmentStore.Controls.Add lblComparison2
// Label: Comparison 3
let lblComparison3 = new Label()
lblComparison3.Left <- 12
lblComparison3.Top <- 168
lblComparison3.Width <- 500
lblComparison3.Text <- "Item 279403 compared to 293041 produces: " + comparison3.ToString()
departmentStore.Controls.Add lblComparison3
do Application.Run departmentStore
This would produce:
As mentioned for disposing of an object, there are two main
ways you can use the IFormatProvider. You can create a class
that implements it. The IFormatProvider is equipped with only one method:
GetFormatIn most cases, you will use classes that already implement
the IFormatProvider interface. Those classes are equipped with an overridden
version of the ToString() method that takes IFormatProvider as argument.
Its signature is:This ToString() method whose signature is:
Finally
End Try
Try
Finally
End Try
Instead of simply adding a new node at the end of child
nodes, you can specify any other position you want. For example, you may want
the new node to precede an existing child node. To support this operation, the XmlNode
class provides the InsertBefore() method. Its syntax is:
Public Overridable Function InsertBefore(ByVal newChild As XmlNode,
ByVal refChild As XmlNode) As XmlNode
The first argument of this method is the new node that will
be added. The second argument is the sibling that will succeed the new node.
Consider the following version of our Videos.xml file:
<?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
<category>Comedy</category>
</video>
<video>
<title>Fatal Attraction</title>
<director>Adrian Lyne</director>
<length>119 Minutes</length>
<format>DVD</format>
<rating>R</rating>
</video>
</videos>
Imagine you want to create a new category element below the
director element whose name is Adrian Lyne. You can first get a list of videos.
Inside of each video, check the nodes and find out whether the video has a
director node whose text is Adrian Lyne. Once you find that node, you can add
the new element after it. Here is an example:
open System
open System.IO
open System.Xml
open System.Drawing
open System.Windows.Forms
let exercise = new Form(MaximizeBox = false, Text = "Video Collection",
ClientSize = new System.Drawing.Size(225, 120),
StartPosition = FormStartPosition.CenterScreen)
let btnDocument = new Button(Text = "Document", Location = new Point(12, 12), Width = 100)
exercise.Controls.Add btnDocument
let btnDocumentClick _ =
let strFileName = "..\..\Videos.xml"
let xdVideos : XmlDocument = new XmlDocument()
if File.Exists strFileName then
use fsVideo = new FileStream(strFileName, FileMode.Open, FileAccess.Read)
xdVideos.Load strFileName
fsVideo.Close()
// Create a list of nodes whose name is Title
let xnlVideos : XmlNodeList = xdVideos.GetElementsByTagName "video"
use fsVideo = new FileStream(strFileName, FileMode.Create, FileAccess.Write)
// Now you can check each node of the list
for xnTitle in xnlVideos do
// Within a video, create a list of its children
let xnlChildren : XmlNodeList = xnTitle.ChildNodes
// Visit each child node
for xnChild in xnlChildren do
// If the child node is (a xnChildector and its name is) Adrian Lyne
if xnChild.InnerText = "Adrian Lyne" then
// Create an element named Category
let xeVideo : XmlElement = xdVideos.CreateElement "category"
// Specify the text of the new element
xeVideo.InnerText <- "Drama"
// Insert the new node below the Adrian Lyne node xnChildector
xnTitle.InsertAfter(xeVideo, xnChild)
This would produce:
In the same way, you can insert a new node after a child of
a child (or of a child of a child of a child) of any node.
XmlNode.InsertAfter():
Here are examples:
.ToString("e")
Here is an example of executing the program:
IEnumerator:
Current) MoveNext and Reset). Normally, you will not need to use that property or to call those methods. As we will see in this lesson, the operations are performed behind the scenes for you. You may be concerned with the IEnumerator.
The IEnumerable interface GetEnumerator. Its signature is:
.InIList. It implements both the ICollection and the IEnumerable interfaces:
The IList ListBox is based on a custom class named ObjectCollection. It implements the IList, the ICollection, and the IEnumerable interface:
Here is an example of using the webpage:
This would produce:
lbxManufacturers.Items.Add "Jaguar"
Here is an example of using the webpage:
Here is an example of using the webpage:
lbxManufacturers.Items.Add "Lincoln"
Items.Insert(2, "Ford")
Here is an example of using the webpage:
(
)
.Invoke( milesDriven, rate)
Here is an example of using the webpage:
Here is an example of using the webpage:
Items.Contains("Toyota")
Here is an example of using the webpage:
Here is an example:
Here is an example of testing the program:
Now consider the following file:
<?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
</video>
<video>
<title>Her Alibi</title>
<director>Bruce Beresford</director>
<length>94 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
</video>
</videos>
The root, videos, has a child named video. The video node
has many child nodes. By now, we know how to add a child to the root. We also
saw how to add a grand child with value to the root. To add many (grand)
children to a node, first build the node, add it to the root, then continuously
add the necessary nodes, one at a time, including its name and its optional
value. This would be done as follows:
open System
open System.IO
open System.Xml
open System.Drawing
open System.Windows.Forms
let exercise = new Form(MaximizeBox = false, Text = "Video Collection",
ClientSize = new System.Drawing.Size(225, 120),
StartPosition = FormStartPosition.CenterScreen)
let btnDocument = new Button(Text = "Start XML File", Location = new Point(12, 12), Width = 100)
exercise.Controls.Add btnDocument
let btnDocumentClick _ =
let strFileName = "..\..\Videos.xml"
let xdVideoCollection : XmlDocument = new XmlDocument()
if File.Exists(strFileName) = false then
Using fsVideo As New FileStream(strFileName, FileMode.Create, FileAccess.Write)
xdVideoCollection.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?>" &
"<videos></videos>")
xdVideoCollection.Save(fsVideo)
fsVideo.Close()
Using fsVideo As New FileStream(strFileName, FileMode.Open, FileAccess.Read)
xdVideoCollection.Load fsVideo
fsVideo.Close()
Using fsVideo As New FileStream(strFileName, FileMode.Create, FileAccess.Write)
let xeRoot : XmlElement = xdVideoCollection.DocumentElement
let mutable xeVideo : XmlElement = xdVideoCollection.CreateElement "video"
xeRoot.AppendChild xeVideo |> ignore
xeVideo <- xdVideoCollection.CreateElement "title"
let txtvideo : XmlText = xdVideoCollection.CreateTextNode("The Day After Tomorrow")
xeRoot.LastChild.AppendChild xeVideo |> ignore
xeRoot.LastChild.LastChild.AppendChild txtvideo |> ignore
xeVideo <- xdVideoCollection.CreateElement "director"
let txtvideo : XmlText = xdVideoCollection.CreateTextNode("Roland Emmerich")
xeRoot.LastChild.AppendChild xeVideo |> ignore
xeRoot.LastChild.LastChild.AppendChild txtvideo |> ignore
xeVideo <- xdVideoCollection.CreateElement "length"
let txtvideo : XmlText = xdVideoCollection.CreateTextNode("124 Minutes")
xeRoot.LastChild.AppendChild xeVideo |> ignore
xeRoot.LastChild.LastChild.AppendChild txtvideo |> ignore
xeVideo <- xdVideoCollection.CreateElement "format"
let txtvideo : XmlText = xdVideoCollection.CreateTextNode("DVD")
xeRoot.LastChild.AppendChild xeVideo |> ignore
xeRoot.LastChild.LastChild.AppendChild txtvideo |> ignore
xeVideo <- xdVideoCollection.CreateElement "rating"
let txtvideo : XmlText = xdVideoCollection.CreateTextNode("PG-13")
xeRoot.LastChild.AppendChild xeVideo |> ignore
xeRoot.LastChild.LastChild.AppendChild txtvideo |> ignore
This would produce:
<?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
</video>
<video>
<title>Her Alibi</title>
<director>Bruce Beresford</director>
<length>94 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
</video>
<video>
<title>The Day After Tomorrow</title>
<director>Roland Emmerich</director>
<length>124 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
</video>
</videos>
XmlDocument:
Here is an example that uses a file stream:
This would produce:
let
let
xeParent
let xnlActors : XmlNodeList = xnVideo.ChildNodes
for xnActor in xnlActors do
if xnActor.Name = "actors" then
// Create a new element named Actor
// Specify its name as Actor
let mutable xeVideo : XmlElement = xdVideos.CreateElement "actor"
// Create the text of the new element
let mutable txtActor : XmlText = xdVideos.CreateTextNode "Tom Selleck"
// Add the new Actor element to the Actors node
xnVideo.LastChild.AppendChild xeVideo |> ignore
// Specify the text of the new node
|> ignore
xnVideo.LastChild.LastChild.AppendChild txtActor
xnVideo.LastChild.LastChild.AppendChild txtActor
|