Использование ООП в VB.Net (исходники)

Источник: gotdotnet
Богданов Марат

Когда мы говорим о преимуществах и особенностях реализации объектно-ориентированного подхода (ООП) перед альтернативными методами программирования, в это же самое время мы говорим о достоинствах и способах использования классов. В этой статье я хотел бы поговорить о том, для чего нужны классы, и как их использовать.

Одна из причин, по которой мы должны использовать классы является так называемое "повторное использование кода". Напомним, что в любом классе имеется хотя бы одна функция. Такие функции называются также "методами" или "членами" класса. Используя в свой работе тот или иной класс, мы делаем это потому, что нам нужны те или иные функции-члены этого класса.

Предположим, имеется некий класс, назовем его MyFirstClass, в котором содержатся две функции, рассчитывающие площади фигур RectangleArea и CircleArea. Посмотрим, как эти функции можно вызывать из Windows- или Web-приложений.

Windows-приложение

Создаем новый проект, добавляем к нему модуль класса со следующим кодом:

Public Class MyFirstClass
    Public a, b, r As Double
    Public Function RectangleArea() As Double
Dim s As Double
s = a * b
Return s
    End Function
    Public Function CircleArea() As Double
Dim s As Double
s = Math.PI * Math.Pow(r, 2)
Return s
    End Function
End Class

Далее, переносим на форму кнопку, дважды щелкаем по ней мышкой и в появившемся коде обработчика событий вводим следующий текст:

Dim obj As New MyFirstClass
Dim a, b, r, RectangleArea, CircleArea As Double
obj.a = 3
obj.b = 4
obj.r = 5
RectangleArea = obj.RectangleArea
CircleArea = obj.CircleArea
MsgBox("Rectangle Area is ... " & RectangleArea & " , Circle Area is ..."_
& CircleArea))

Web-приложение

Отличие Web-проекта от Windows-приложения заключается в том, что класс мы должны предварительно откомпилировать, создав из него dll-файл. Итак, нам необходимо открыть блокнот, набрать в нем следующий код:

Imports System
Imports Microsoft.VisualBasic.VBMath
Namespace FigureArea
Public Class MyFirstClass
Public Function RectangleArea(ByVal a As Double, ByVal b As Double) As Double
Dim s As Double
s = a * b
Return s
End Function
Public Function CircleArea(ByVal r As Double) As Double
Dim s As Double
s = Math.PI * Math.Pow(r, 2)
Return s
End Function
End Class
End Namespace

Далее, набранный текст нужно сохранить с именем FigureArea.vb. В папку, где находится этот файл скопировать файл vbc.exe, обычно он находится по адресу C:\WINNT\Microsoft.NET\Framework\v1.1.4322. После этого в командной строке нужно набрать следующий код:

vbc /t:library /r:System.dll FigureArea.vb

В результате чего мы получим файл FigureArea.dll.

Теперь мы создаем Web-проект, в папку \bin копируем файл FigureArea.dll, создаем файл FigureArea.aspx, код которого будет следующий:

<html>
<%@ Import Name-space="FigureArea"%>
<script runat=server language=vb>
Sub btn_Click(s as Object, e As Eventargs)
    Dim obj As New MyFirstClass()
    Dim a,b,r as double
    a=3
    b=4
    r=5
    Dim RectangleArea, CircleArea As Double
    RectangleArea=obj.RectangleArea(a,b)
    CircleArea=obj.CircleArea(r)
    lbl.Text="Площадь прямоугольника = " & RectangleArea &  " , площадь _
круга = " & CircleArea
End Sub
</script>
<body>
<form id="Form1" method="post" runat="server">
<asp:Button ID=btn OnClick=btn_click Runat=server Text="Click me!"/>
<br>
<asp:Label ID=lbl Runat=server/>
</form>
</body>
</html>

Из листинга видно, что мы в начале создаем объектную переменную, связанную с классом MyFirstClass, а затем вызываем функции-члены класса, подставляя в них фактические параметры (obj.RectangleArea(a, b) и obj.CircleArea(r)).

Посмотрим, что у нас получилось. И в первом и во втором случаях, мы вызываем функции-члены класса, используя объектную переменную. Очевидно, что если наш Web-проект состоит только из одной ASP.Net-странички, а Windows-приложение - только из одной формы, многократного использования кода не получится, проще пользоваться отдельными функциями. Однако когда речь идет о сайте, состоящем из сотен Web-страничек, использующих одни и те же функции, в этом случае выигрыш будет очевиден (так как функции-члены класса доступны для всего проекта).

Вторым плюсом использования откомпилированных в .dll-файл классов является защита интеллектуальной собственности, так как внутреннее содержимое класса скрыто в .dll-файле.

Ключевое слово New

Ключевое слово New указывает VB.Net создать новый экземпляр класса MyFirstClass. Объявление переменной без этого ключевого слова, говорит компилятору, что мы планируем хранить в переменной экземпляр класса, но пока этот экземпляр создавать не нужно. Когда мы захотим инициализировать переменную, достаточно будет задать отдельную строку с ключевым словом New:

Dim obj As New MyFirstClass()

При попытке обратиться к переменной, объявленной без ключевого слова New и не инициализированной с помощью приведенной выше инструкции, будет сгенерировано исключение "Null Reference". Это исключение означает, что переменная имеет значение Null, то есть она еще не инициализирована.

Задание:

Разработайте программу, находящую площадь трапеции.

Разработайте программу, находящую объем тора.

Ранее было сказано о том, что в любом классе есть хотя бы одна функция. Как известно, обычно у функций бывают аргументы. В предыдущем примере было показано, как можно подставлять фактические значения аргументов функций. В первом случае переменные a, b и r имели глобальную область видимости (Public a As Double) и мы их инициализировали в вызывающем приложении (obj.a = 3). Во втором случае фактические параметры мы подставляли при вызове функций (RectangleArea = obj.RectangleArea(a,b)).

У показанных здесь способов использования аргументов функций-членов класса есть определенные недостатки. Дело заключается в том, что зачастую бывает желательно перед подстановкой аргумента убедиться в том, что он удовлетворяет определенным условиям (например, возраст человека не может быть отрицательным числом).

В таких случаях между вызывающим приложением и функциями-членами класса вводят особых посредников - так называемые свойства класса ( Properties ).

Свойства обычно являются общедоступными переменными класса, то есть они видны в вызывающем приложении, наряду с ними в классах обычно еще используются переменные с локальной областью видимостью ( private ), доступные только в данном классе, они являются аргументами функций-членов класса. Свойства состоят из двух разделов: Set и Get . Работа со свойствами производится следующим образом. В вызывающем приложении свойству присваивается некоторая величина, далее, в разделе Set свойства производится проверка области допустимых значений. Если проверка прошла хорошо, то это значение присваивается некой локальной переменной класса в разделе Get , которая, как мы знаем, является аргументом некой функции класса. В противном случае, или выдается сообщение об ошибке, или срабатывает так называемый обработчик исключений (об этом ниже). То есть, свойства класса являются некими шлюзами между вызывающим приложением и функциями-членами класса.

В следующем примере программа выдает на экран одно из семи изречений. Пользователь должен ввести любую цифру от 1 до 7.

Вернемся к нашему Windows-приложению. Добавим еще один класс (OracleClass) со следующим содержимым:

Public Class OracleClass
Private n As Integer
Property RandomNumber() As Integer
Get
RandomNumber = n
End Get
Set(ByVal Value As Integer)
If Value > 7 Then
MsgBox("Не выполняется область допустимых значений!!!")
Else
n = Value
End If
End Set
End Property
Public Function Maxim(ByVal n As Integer) As String
Dim Saying() As String = _
{"Без труда не выловишь и рыбки из пруда", _
"Ранней пташке Бог подает", _
"Ум хорошо, а два лучше", _
"Рука руку моет", _
"Старый друг лучше новых двух", _
"За одного битого двух небитых дают", _
"Сам погибай, а товарища выручай"}
Select Case n
Case 1
Return Saying(0)
Case 2
Return Saying(1)
Case 3
Return Saying(2)
Case 4
Return Saying(3)
Case 5
Return Saying(4)
Case 6
Return Saying(5)
Case Else
Return Saying(6)
End Select
End Function
End Class
Затем, в форме размещаем поле вода со свойством Name txtNumber и кнопку, в обработчике событий которой вводим следующее:

Dim n As Integer
n = txtNumber.Text
Dim obj As New OracleClass()
obj.RandomNumber = n
Dim Adage As String
Adage = obj.Maxim(n)
MsgBox(Adage)

Общедоступная функция Maxim возвращает поговорку в строковом формате в зависимости от введенного пользователем номера. Если этот номер больше семи, то в разделе Set номер приравнивается нулю, выдается сообщение об ошибке, а функция возвращает первую фразу.

Задание:

Разработайте программу, выводящую на экран имена семи гномов из сказки "Белоснежка".

Разработайте программу, выводящую на экран 10 заповедей.

Разработайте программу, выводящую на экран 7 смертных грехов

В следующем примере мы рассмотрим использование обработчиков исключений. Предлагаемая программа генерирует неповторяющуюся последовательность целых чисел в заданном диапазоне.

Вновь вернемся к нашему Windows-приложению.

Создаем класс RandomClass со следующим кодом:

Public Class RandomClass
Private a, b, n As Integer
Property LowerLevel() As Integer
Get
LowerLevel = a
End Get
Set(ByVal Value As Integer)
If Value < 0 Then
Dim LowerLevelException As New ArgumentException()
Throw LowerLevelException
Else
a = Value
End If
End Set
End Property
Property UpperLevel() As Integer
Get
UpperLevel = b
End Get
Set(ByVal Value As Integer)
If Value < 0 Then
Dim UpperLevelException As New ArgumentException()
Throw UpperLevelException
Else
b = Value
End If
End Set
End Property
Property TestingNumber() As Integer
Get
TestingNumber = n
End Get
Set(ByVal Value As Integer)
If Value < 0 Then
Dim TestingNumberException As New ArgumentException()
Throw TestingNumberException
Else
n = Value
End If
End Set
End Property
Public Function RandomArray(ByVal a As Integer, ByVal b As Integer, ByVal n _
As Integer) As ArrayList
Dim RList As New ArrayList()
Dim alpha, i As Integer
i = 0
Randomize()
RList.Add(CInt(((b - 1) * Rnd() + a)))
Do Until i = n - 1
alpha = CInt(((b - 1) * Rnd() + a))
If RList.Contains(alpha) = True Then
Else
RList.Add(alpha)
i += 1
End If
Loop
RandomArray = RList
End Function
End Class

Из листинга видно, что класс содержит три свойства LowerLevel, Upper-Level и TestingNumber (нижний предел, верхний предел и количество испытаний), а также функцию RandomArray, генерирующую массив случайных чисел. В разделах Set данных свойств проводится проверка того, чтобы введенные значения были положительными, если требование удовлетворяется, то значения, введенные пользователем в вызывающей программе (см. ниже) присваиваются локальным переменным класса a, b и n в соответствующих разделах Get , в противном случае срабатывают обработчики исключений LowerLevelException, UpperLevelException и Testing-NumberException, которые обрабатываются в вызывающем приложении.

Далее разместим в форме три поля ввода txtA, txtB и txtN, и кнопку, со следующим кодом:

'Инициализируем экземпляр класса MyRandomList
Dim obj As New RandomClass()
Dim a As Integer 'Нижний предел
Dim b As Integer 'Верхний предел
Dim n As Integer 'Количество испытаний, должно быть меньше или равно _
верхнему пределу
a = txtA.Text
b = txtB.Text
n = txtN.Text
Try
obj.LowerLevel = a
Catch LowerLevelException As ArgumentException
MsgBox("Минимальное значение не может быть меньше нуля!")
obj.LowerLevel = Math.Abs(a)
End Try
Try
obj.UpperLevel = b
Catch UpperLevelException As ArgumentException
MsgBox("Максимальное значение не может быть меньше нуля!")
obj.UpperLevel = Math.Abs(b)
End Try
Try
obj.TestingNumber = n
Catch TestingNumberException As ArgumentException
MsgBox("Количество испытаний не может быть меньше нуля!")
obj.TestingNumber = Math.Abs(n)
End Try
Dim RandomList As New ArrayList()
RandomList = obj.RandomArray(obj.LowerLevel, obj.UpperLevel, _
obj.TestingNumber)
Dim i As Integer
Dim strRandomList As String
For i = 0 To Math.Abs(n) - 1
strRandomList &= RandomList(i) & vbCrLf
Next i
MsgBox(strRandomList)

Из листинга видно, как работают обработчики исключений: в случае отрицательных значений, веденных пользователем, величины заменяются модулем этих чисел.

Задание:

Разработайте программу, решающую квадратное уравнение, причем таким образом, чтобы коэффициент a не превышал 30, коэффициент b - 40, а c - 50.

Инкапсуляция и абстракция

Инкапсуляция классов означает, что для тех, кто использует данный класс, последний представляется в виде "черного ящика". Из житейского опыта мы знаем, что для того, чтобы, скажем, переключить канал в телевизоре, нет необходимости самому настраивать переключатель телевизионных каналов, достаточно воздействовать на соответствующий орган управления, расположенный на пульте дистанционного управления (являющегося "элементом интерфейса" телевизора). То же самое можно и сказать о прибавлении "газа" в автомобиле. В классах интерфейс образуют свойства и методы последних.

Абстракция означает, что классы позволяют скрыть некую сложную внутреннюю структуру объекта, позволяя программисту сосредоточиться на программировании более высокого уровня. Особенно удобен подобный подход при командной разработке клиент-серверных приложений. При этом один участник проекта может разработать базу данных и функции-методы доступа к данным, заключенные в соответствующем классе, например, DataBaseClass(), избавляя разработчика клиентского приложения от необходимости глубоко вникать во внутреннюю структуру БД. При этом, последний просто создает объектную переменную (Dim obj As New DataBaseClass()), связанную с соответствующим классом и вызывает функции типа obj.SaveProduct() или obj.AddCustomer().

Предположим, что нам требуется создать приложение, которое вводило бы сведения о преподавателях некоего университета в базу данных отдела кадров. При этом программа должна следить за тем, чтобы идентификационные номера преподавателей были уникальными. Предполагается, что проект большой, и один из программистов разрабатывает серверную часть проекта, записывающую в базу данных сведения о преподавателях, а другой - создает клиентское приложение, при этом он может ничего не знать о структуре базы данных.

Серверная часть

В начале требуется создать каталог teacher на диске C. В нем будут находиться файлы базы данных. Затем нужно запустить Анализатор запросов (Query Analyzer) СУБД Microsoft SQL Server 2000 и выполнить следующий код:

USE master
GO
/* Удаляем базу данных при ее обнаружении */
IF DB_ID('teacher') IS NOT NULL
BEGIN
DROP DATABASE teacher
END
--Создаем базу данных teacher в каталоге c:\teacher
CREATE DATABASE teacher --ON PRIMARY
ON 
( NAME = teacher_dat,
 FILENAME = 'c:\teacher\teacher.mdf',
 SIZE = 10MB,
-- MAXSIZE = 50,
 FILEGROWTH = 5% )
LOG ON
( NAME = 'teacher_log',
 FILENAME = 'c:\teacher\teacher.ldf',
 SIZE = 5MB,
-- MAXSIZE = 25MB,
 FILEGROWTH = 5% )
GO
USE teacher
GO
exec sp_helpdb teacher
-- Создаем таблицу преподавателей
IF OBJECT_ID('TEACHER_TBL') IS NOT NULL
DROP TABLE dbo.TEACHER_TBL
GO
CREATE TABLE TEACHER_TBL
(
TEACHER_ID INT PRIMARY KEY,-- Первичный ключ
TEACHER_FIRST_NAME NVARCHAR(400) NULL, -- Имя преподавателя
TEACHER_MIDDLE_NAME NVARCHAR(400) NULL, -- Фамилия преподавателя
TEACHER_LAST_NAME NVARCHAR(400) NULL, -- Отчество преподавателя
TEACHER_WORKPLACE NVARCHAR(400) NULL, -- Место работы преподавателя
TEACHER_EMAIL NVARCHAR(400) NULL, -- Электронный адрес преподавателя
TEACHER_PASSWORD NVARCHAR(400) NULL -- Пароль преподавателя
)
GO
--Создаем хранимую процедуру, вводящую преподавателей с уникальными паролями
IF OBJECT_ID('ADD_UNIQUE_TEACHER_PROC') IS NOT NULL
DROP PROCEDURE dbo.ADD_UNIQUE_TEACHER_PROC
GO
CREATE PROCEDURE ADD_UNIQUE_TEACHER_PROC
(
@TEACHER_ID INT , -- Первичный ключ
@TEACHER_FIRST_NAME NVARCHAR(400), -- Имя преподавателя
@TEACHER_MIDDLE_NAME NVARCHAR(400), -- Фамилия преподавателя
@TEACHER_LAST_NAME NVARCHAR(400), -- Отчество преподавателя
@TEACHER_WORKPLACE NVARCHAR(400), -- Место работы преподавателя
@TEACHER_EMAIL NVARCHAR(400), -- Электронный адрес преподавателя
@TEACHER_PASSWORD NVARCHAR(400) -- Идентификационный номер преподавателя
)
As
If Exists
(
SELECT TEACHER_PASSWORD
FROM TEACHER_TBL
WHERE TEACHER_PASSWORD=@TEACHER_PASSWORD
)
Return 1
Else
Insert TEACHER_TBL (TEACHER_ID, TEACHER_FIRST_NAME, TEACHER_MIDDLE_NAME, 
    TEACHER_LAST_NAME, TEACHER_WORKPLACE, TEACHER_EMAIL, TEACHER_PASSWORD) 
    Values (@TEACHER_ID, @TEACHER_FIRST_NAME, @TEACHER_MIDDLE_NAME, 
    @TEACHER_LAST_NAME, @TEACHER_WORKPLACE, @TEACHER_EMAIL, @TEACHER_PASSWORD)
GO

Как видно из листинга, база данных состоит из одной таблицы (TEACHER_TBL) и одной хранимой процедуры (ADD_UNIQUE_TEACHER_PROC), отвечающей за уникальность идентификационного номера преподавателей.

Затем, создаем Web-приложение, в блокноте набираем следующий код:

Imports System
Imports System.Collections
Imports Microsoft.VisualBasic.VBMath
Imports System.Data.SqlClient.SqlConnection
Imports System.Data.SqlClient.SqlCommand
Imports System.ComponentModel.Component
Imports System.Web
Imports System.Web.UI
Imports System.Data
Namespace AddTeacher
Public Class AddTeacherClass
Private strConnection As String = "Integrated Security=SSPI; _
Initial Catalog=teacher"
Public TEACHER_FIRST_NAME As String
Public TEACHER_MIDDLE_NAME As String
Public TEACHER_LAST_NAME As String
Public TEACHER_WORKPLACE As String
Public TEACHER_EMAIL As String
Public TEACHER_PASSWORD As String
Function GetPrimaryKey() As Integer
Randomize()   'Запускаем генератор случайных чисел
Dim lowerbound, upperbound, PrimaryKey As Integer 
' Верхний и нижний пределы генерации случайных чисел
lowerbound = 1
upperbound = upperbound.MaxValue
PrimaryKey = CInt((upperbound - lowerbound + 1) * Rnd() + lowerbound)
Return PrimaryKey
End Function
Public Function AddTeacher() As String
Dim TEACHER_ID As Integer 'Первичный ключ
TEACHER_ID = GetPrimaryKey()
Dim conTeacher As Sys-tem.Data.SqlClient.SqlConnection
Dim cmdAddUniqueTeacher As System.Data.SqlClient.SqlCommand
Dim parmReturnValue As System.Data.SqlClient.SqlParameter
conTeacher = New System.Data.SqlClient.SqlConnection(strConnection)
cmdAddUniqueTeacher = New _
System.Data.SqlClient.SqlCommand("ADD_UNIQUE_TEACHER_PROC", conTeacher)
cmdAddUniqueTeacher.CommandType = System.Data.CommandType.StoredProcedure
parmReturnValue = cmdAddUniqueTeacher.Parameters.Add("ReturnValue", _
System.Data.SqlDbType.Int)
parmReturnValue.Direction = System.Data.ParameterDirection.ReturnValue
cmdAddUniqueTeacher.Parameters.Add("@TEACHER_ID", TEACHER_ID)
cmdAddUniqueTeacher.Parameters.Add("@TEACHER_FIRST_NAME", TEACHER_FIRST_NAME)
cmdAddUniqueTeacher.Parameters.Add("@TEACHER_MIDDLE_NAME", _
TEACHER_MIDDLE_NAME)
cmdAddUniqueTeacher.Parameters.Add("@TEACHER_LAST_NAME", TEACHER_LAST_NAME)
cmdAddUniqueTeacher.Parameters.Add("@TEACHER_WORKPLACE", TEACHER_WORKPLACE)
cmdAddUniqueTeacher.Parameters.Add("@TEACHER_EMAIL", TEACHER_EMAIL)
cmdAddUniqueTeacher.Parameters.Add("@TEACHER_PASSWORD", TEACHER_PASSWORD)
conTeacher.Open()
cmdAddUniqueTeacher.ExecuteNonQuery()
Dim strMessage As String
If cmdAddUniqueTeacher.Parameters("ReturnValue").Value = 0 Then
    strMessage = "Данные введены успешно!"
Else
    strMessage = "Идентификационный номер преподавателя не уникален, _
повторите ввод!"
End If
conTeacher.Close()
Return strMessage

End Function End Class End Namespace

Сохраняем файл с именем AddTeacher.vb, компилируем его, как было показано выше, набирая в командной строке:

vbc /t:library /r:System.dll,System.Web.dll,System.Data.dll,System.XML.dll AddTeacher.vb

Полученный файл AddTeacher.dll также копируем в папку /bin нашего проекта. Теперь можно приступить к созданию клиентской части проекта.

Клиентская часть

Клиентская часть представлена одной ASP.Net-страничкой AddLecturer.aspx со следующим кодом:

<html>
<%@ Import Name-space="AddTeacher"%> 
<script runat="server" language="vb">
Sub btn_Click(s as object, e as EventArgs)
Dim obj as new AddTeacherClass()
Dim TEACHER_FIRST_NAME As String
Dim TEACHER_MIDDLE_NAME As String
Dim TEACHER_LAST_NAME As String
Dim TEACHER_WORKPLACE As String
Dim TEACHER_EMAIL As String
Dim TEACHER_PASSWORD As String
obj.TEACHER_FIRST_NAME="Михаил"
obj.TEACHER_MIDDLE_NAME="Ломоносов"
obj.TEACHER_LAST_NAME="Васильевич"
obj.TEACHER_WORKPLACE="МГУ им. Ломоносова"
obj.TEACHER_EMAIL="michael@mail.ru"
obj.TEACHER_PASSWORD="lomonosov"
lbl.Text=obj.AddTeacher()
End Sub
</script>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:Button ID="btn" OnClick="btn_Click" Runat="server" Text="Click me!"/>
<br>
<asp:Label ID=lbl Runat=server/>
</form>
</body>
</html>

Из листинга видно, что для того, чтобы добавить сведения о преподавателе в базу данных совершенно необязательно знать структуру этой БД. Достаточно объявить объектную переменную (Dim obj as new AddTeacherClass()), заполнить необходимые поля класса и вызвать функцию AddTeacher().

Задание

Создайте базу данных, состоящую из одной таблицы и одной хранимой процедуры, подсчитывающей количество строк в таблице примерно следующего содержания:

Create Procedure GetAuthorCountAsReturn (Select Count(*) From Authors)GO

Разработайте программу, выводящую на экран количество строк этой таблицы по аналогии с предыдущим примером.

Создайте базу данных, состоящую из одной таблицы. Разработайте программу, предназначенную для занесений информации в эту таблицу. Класс должен содержать процедуру NonQueryMethod (листинг приводится ниже). Переменная strConnection - строка подключения, например , strConnection ="Integrated Security=SSPI; Initial Catalog=Northwind", другая переменная - QueryString - запрос на языке SQL, например , QueryString="insert into Shippers(CompanyName, Phone) Values ('IBM','+7(3472)221109')".

Sub NonQueryMethod(ByVal QueryString As String, ByVal strConnection _
As String)
Dim sqlConnection As System.Data.SqlClient.SqlConnection = _
New System.Data.SqlClient.SqlConnection(strConnection)
Dim sqlCommand As System.Data.SqlClient.SqlCommand = _
New System.Data.SqlClient.SqlCommand(QueryString, sqlConnection)
sqlConnection.Open()
Try
sqlCommand.ExecuteNonQuery()
Finally
sqlConnection.Close()
End Try
End Sub

Создайте базу данных, состоящую из одной таблицы. Разработайте программу, предназначенную для удаления информации из этой таблицы, используя процедуру NonQueryMethod. Параметр QueryString в этом случае будет примерно таким: "Delete from Shippers where ShipperID=4".

Создайте базу данных, состоящую из одной таблицы. Разработайте программу, предназначенную для изменения информации в этой таблице, используя процедуру NonQueryMethod. Параметр QueryString в этом случае будет примерно таким: "update Shippers set CompanyName='ООО "Рога и копыта"', Phone='+7(3472)02' where ShipperID=5".

Наследование и полиморфизм

Классы расширяются путем создания новых классов, наследующих их функции. Это означает создание нового класса на основе существующего. Исходный класс называется родительским или базовым. Производный класс наследует все функции базового класса, при этом обычно, в него добавляются новые функции или заменяются существующие. Помимо этого в производном классе могут быть перегружены методы исходного класса, т.е. добавлены новые формы этих методов, принимающие другие аргументы.

Рассмотрим программу, производящую дифференцирование и интегрирование функций. Возвращаемся к нашему Windows-приложению. Добавляем в него класс MyFunction со следующим кодом:

Public Class MyFunction
Overridable Function Derivative() As Double
End Function
Overridable Function Integral() As Double
End Function
End Class

Класс MyFunction будет родительским. Функции Derivative и Integral будут наследоваться в производных классах. Ключевое свойство Overridable означает, что все классы, наследующие класс MyFunction, могут заменять стандартную реализацию соответствующего метода или свойства.

На основе родительского класса MyFunction создадим три производных класса, предназначенные для нахождения производных и интегралов для таких функций, как y=x2, y=cos(x), y=sqrt(x) (Square_X, Cosine и SquareRoot_X).

Public Class Square_X
Inherits MyFunction
Private x As Double
Private x_min, x_max As Double
Public Property Quantity() As Double
Get
Quantity = x
End Get
Set(ByVal Value As Double)
x = Value
End Set
End Property
Sub New(ByVal Quantity As Double)
MyBase.new()
x = Quantity
End Sub
Public Overrides Function Derivative() As Double
Return (2*x)
End Function
Public Property min_value() As Double
Get
min_value = x_min
End Get
Set(ByVal Value As Double)
x_min = Value
End Set
End Property
Public Property max_value() As Double
Get
max_value = x_max
End Get
Set(ByVal Value As Double)
x_max = Value
End Set
End Property
Sub New(ByVal max_value As Double, ByVal min_value As Double)
MyBase.new()
x_max = max_value
x_min = min_value
End Sub
Public Overrides Function Integral() As Double
Return ((1/3) * (Math.Pow(x_max, 3) - Math.Pow(x_min, 3)))
End Function
End Class
Public Class Cosine
Inherits MyFunction
Private x As Double
Private x_min, x_max As Double
Public Property Quantity() As Double
Get
Quantity = x
End Get
Set(ByVal Value As Double)
x = Value
End Set
End Property
Sub New(ByVal Quantity As Double)
MyBase.new()
x = Quantity
End Sub
Public Overrides Function Derivative() As Double
Return (-Math.Sin(x))
End Function
Public Property min_value() As Double
Get
min_value = x_min
End Get
Set(ByVal Value As Double)
x_min = Value
End Set
End Property
Public Property max_value() As Double
Get
max_value = x_max
End Get
Set(ByVal Value As Double)
x_max = Value
End Set
End Property
Sub New(ByVal max_value As Double, ByVal min_value As Double)
MyBase.new()
x_max = max_value
x_min = min_value
End Sub
Public Overrides Function Integral() As Double
Return (Math.Sin(x_max) - Math.Sin(x_min))
End Function
End Class

Public Class SquareRoot_X Inherits MyFunction Private x As Double Private x_min, x_max As Double Public Property Quantity() As Double Get Quantity = x End Get Set(ByVal Value As Double) x = Value End Set End Property Sub New(ByVal Quantity As Double) MyBase.new() x = Quantity End Sub Public Overrides Function Derivative() As Double Return (1/(2*Math.Sqrt(x))) End Function Public Property min_value() As Double Get min_value = x_min End Get Set(ByVal Value As Double) x_min = Value End Set End Property Public Property max_value() As Double Get max_value = x_max End Get Set(ByVal Value As Double) x_max = Value End Set End Property Sub New(ByVal max_value As Double, ByVal min_value As Double) MyBase.new() x_max = max_value x_min = min_value End Sub Public Overrides Function Integral() As Double Return ((2/3) * (Math.Pow(x_max, (1/3)) - Math.Pow(x_min, (1/3)))) End Function End Class

Вы, наверное, заметили, что в каждом производном классе присутствует ключевое слово Inherits MyFunction, означающее, что родительским классом является класс MyFunction. Ключевое слово New используется при создании так называемого конструктора класса. Конструктор представляет собой подпрограмму New, определенную внутри класса и вызываемую всякий раз, когда создается новый экземпляр класса. Именно в такую подпрограмму обычно включается инициализационный код, выполняющий операции, подобные открытию файла или подключение к базе данных. В процедуре New существует подпрограмма MyBase.New, позволяющая получить доступ к членам базового класса.

Sub New(ByVal max_value As Double, ByVal min_value As Double)
MyBase.new()
x_max = max_value
x_min = min_value
End Sub

Конструктор класса позволяет при создании экземпляра класса сразу же его инициализировать, например, так:

Dim myIntegral As New SquareRoot_X(5.6, 10.5)

Если объект (экземпляр класса) уже не нужен, его можно установить в Nothing. При этом так называемый "уборщик мусора" (Garbage Collector) удалит его из оперативной памяти.

myIntegral= Nothing 'Деструктор объекта

Добавим к форме кнопку и три поля ввода txtDerivative, txtMin, txtMax (значения, подставляемые в формулу производной функции, а также верхний и нижний пределы интегрирования).

В обработчике событий кнопки введем следующий код:

Dim Derivative, Min, Max As Double
Derivative = txtDerivative.Text
Min = txtMin.Text
Max = txtMax.Text
Dim Square_X_Derivative As New Square_X(Derivative)
Dim strSquare_X_Derivative, strSquare_X_Integral As String
Dim Square_X_Integral As New Square_X(Max, Min)
strSquare_X_Derivative = Square_X_Derivative.Derivative.ToString 
'Значение производной в точке Derivative
strSquare_X_Integral = Square_X_Integral.Integral.ToString 
'Значение определенного интеграла в диапазоне от Min до Max
MsgBox("Функция y=x^2: Производная в точке " & Derivative & " равна " _
& strSquare_X_Derivative & " , Интеграл в диапазоне от " & Min & " до " _
& Max & " равен " & strSquare_X_Integral)
Square_X_Derivative = Nothing 'Деструктор объекта
Square_X_Integral = Nothing 'Деструктор объекта
Dim Cosine_Derivative As New Cosine(Derivative)
Dim strCosine_Derivative, strCosine_Integral As String
Dim Cosine_Integral As New Cosine(Max, Min)
strCosine_Derivative = Cosine_Derivative.Derivative.ToString
strCosine_Integral = Cosine_Integral.Integral.ToString
MsgBox("Функция y=Cos(x): Производная в точке " & Derivative & " равна " _
& strCosine_Derivative & " , Интеграл в диапазоне от " & Min & " до " & _
Max & " равен " & strCosine_Integral)
Square_X_Derivative = Nothing 'Деструктор объекта
Square_X_Integral = Nothing 'Деструктор объекта
Dim SquareRoot_X_Derivative As New SquareRoot_X(Derivative)
Dim strSquareRoot_X_Derivative, strSquare-Root_X_Integral As String
Dim SquareRoot_X_Integral As New SquareRoot_X(Max, Min)
strSquareRoot_X_Derivative = SquareRoot_X_Derivative.Derivative.ToString
strSquareRoot_X_Integral = SquareRoot_X_Integral.Integral.ToString
MsgBox("Функция y=sqrt(x): Производная в точке " & Derivative & " равна " _
& strSquareRoot_X_Derivative & " , Интеграл в диапазоне от " & Min & " до " _
& Max & " равен " & strSquareRoot_X_Integral)
Square_X_Derivative = Nothing 'Деструктор объекта
Square_X_Integral = Nothing 'Деструктор объекта

Задание

Разработайте программу, подсчитывающую объем и поверхность цилиндра, конуса и пирамиды.

Подытожив вышеизложенное, хотелось бы высказать свои соображения относительно того, в каких случаях нужно использовать классы.

  1. Если проект состоит из большого количества ASP.Net-страничек или форм, использующих одни и те же функции.
  2. Если необходимо защитить интеллектуальную собственность на бизнес-логику проекта.
  3. Если над проектом работает несколько человек, зачастую разной квалификации, и для удобства бывает необходимо скрыть сложность и внутреннюю структуру различных частей приложения.
  4. Если моделируемый объект имеет иерархическую структуру по аналогии с систематикой животного или растительного царства.

Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=6969