:: Меню ::

Головна
  • Про сайт
  • Введення
  • Середовище програмування VB .NET: Visual Studio .NET
  • Вирази, оператори і передача управління
  • Класи і об'єкти
  •  Спадкоємство і інтерфейси
  • Обробка подій і делегати
  • Обробка помилок в VB .NET
  • Форми Windows, графічний вивід і друк
  • Уведення-виведення
  •  Багатопотокові застосування
  • Підтримка баз-даних в VB .NET
  • Короткий огляд ASP .NET
  • Складки .NET, установка додатків і COM Interop
  • Книга для гостей
    Контакти
    Добавити у вибране

    :: Друзі ::

     
     

    :: Лічильники ::

    = =

     

     

     

     

    Визначення класів в програмі

    Від використання готових класів .NET Framework ми переходимо до визначення власних класів в програмі. Код класу можна розмістити в окремому файлі за допомогою команди Project > Add Class, як в Vb6, або ж просто ввести його в потрібному модулі — наприклад, в стартовому модулі, що містить точку входу в консольне застосування.

    В процесі тестування ми вважаємо за краще пов'язувати кожен клас з процедурою Sub Main, в якій він використовується. Таким чином, код класів не оформляється у вигляді окремих модулів класів, а виділяється в програмний модуль з окремою процедурою Sub Main, призначеною для їх тестування. Якщо ви підете нашому прикладу, врахуйте, що код, визначуваний на рівні модуля, доступний скрізь, де доступний сам модуль. Таким чином, ми створюємо якийсь аналог глобальних змінних і функцій VB .NET — зі всіма небезпеками, властивими глобальним даним.

    VB .NET не дивиться на те, скільки класів визначається в одному файлі. У більшості класів визначаються один або два конструктори, властивості для читання і зміни стану об'єкту, а також методи для виконуваних дій. Для прикладу візьмемо простий клас Empl oyee з двома полями (ім'я і зарплата) і невелику тестову програму. У класі визначаються дві властивості, доступних тільки для читання; ці властивості повертають значення полів. Методи в цьому класі відсутні:

    1 Module Employeetestl

    2 Sub Main()

    3 Dim Tom As New Employee("Tom". 100000)

    4 Console.WriteLine(Tom.TheName & "salary is " & Tom.Salary)

    5 Console. Readline()

    6 End Sub

    7 ' Визначення класу

    8 Public Class Employee

    9 Private m_name As String

    10 Private m_salary As Decimal

    11 Public Sub New(Byva1 sname As String.ByVal cursalary As Decimal)

    12 m_name = Sname

    13 m_salary = cursalary

    14 End Sub

    15 Public Readonly Property Thename()As String

    16 Get

    17 Return m_name

    18 End Get

    19 End Property

    20 Public Readonly Property Salary() As Decimal

    21 .Get .

    22 Return m_salary

    23 End Get

    24 End Property

    25 End Class

    26 End Module

    У рядках 2—6 визначається процедура Sub Main, використовувана компілятором як точка входу. Якщо ця процедура вибрана як стартовий об'єкт (це відбувається за умовчанням, але взагалі стартовий об'єкт вибирається в діалігвом вікні Project Properties), вона відповідає за створення початкових екземплярів. Далі створені об'єкти зазвичай створюють інші об'єкти у відповідь на отримання ними повідомлень. Звичайно, в нашій простий програмі нічого такого не відбувається.

    Безпосереднє створення об'єкту відбувається в рядку 3, що грає ключову роль в процесі тестування програми. У цьому рядку при створенні нового об'єкту Empl oyee методу New передаються два параметри — ім'я і початкова зарплата. У рядку 4 ми виводимо значення властивостей Thename і Salагу, щоб переконатися в тому, що початковий стан створеного об'єкту був заданий вірно.

    Клас Empl oyee визначається в рядках 8-25. Як згадувалося вищим, для зручності тестування код класу визначається в початковому модулі, хоча ми з таким же успіхом могли скористатися командою Project > Add Class і виділити його в окремий файл.

    Давайте уважно розглянемо кожен рядок у визначенні класу. У рядку 8 ключове слово Publiс є атрибутом рівня доступу і визначає, кому дозволено створювати екземпляри цього класу. У нашому прикладі клас оголошений відкритим, тому теоретично будь-який охочий зможе створювати його екземпляри після компіляції — для цього в програму досить включити посилання на збірку, що містить цей клас (складки розглядаються в розділі 13). Щоб клас міг використовуватися тільки в рамках нашого проекту і залишався недоступним для зовнішніх програм, ключове слово Public слід замінити ключовим словом Friend.

    У рядках 9 і 10 визначаються закриті поля для зберігання інформації про стан об'єкту. В черговий раз нагадаємо, що змінні завжди повинні оголошуватися закритими (Private). У своїх визначеннях класів і модулів ми завжди починаємо імена полів з префікса m_ або m.

    У рядках 11-14 визначається конструктор, призначений для створення екземплярів класу. Конструктор задає значення закритих полів екземпляра відповідно до значень отриманих параметрів.

    У рядках 15-19 і 20-24 визначаються дві відкриті властивості, доступних тільки для читання. Вони призначені для отримання інформації про поточний стан об'єкту. У приведеному прикладі використано ключове слово Return, проте з таким же успіхом можна було застосувати старий синтаксис з привласненням імені властивості:

    Get

    Thename = m_name

    End Get

    Втім, навіть в цій формі синтаксис процедури властивості дещо змінився в порівнянні з Vb6 — зникли старі конструкції Property Get/property Set.

    Наступна версія програми показує, як зробити властивість Salary доступною для читання і запису. Для цього досить видалити ключове слово Readonly і додати невеликий фрагмент:

    Public Property Salary()As Decimal Get

    Return m_salary End Get Set(Byval Value As Decimal)

    m_salary = Value

    End Set

    End Property

    У цьому фрагменті перш за все слід звернути увагу на читання нового значення властивості із застосуванням ключового слова Value. Інакше кажучи, коли в програмі зустрічається рядок виду Tom.Salary = 125000, параметру Value автоматично привласнюється значення 125 000.

    Іноді зустрічаються ситуації, коли властивість потрібно оголосити доступним тільки для запису. Для цього перед ім'ям властивості ставиться ключове слово Writeonly, а потім визначається секція Set без секції Get.

    Допустимо, ми вирішили оголосити властивість Salary доступним тільки для читання і включити в клас метод для підвищення зарплати. Метод оголошується як звичайна процедура або функція. У нашому прикладі метод не повертає значення, тому вибір варто зупинити на процедурі:

    Public Sub Raisesalary(Byval Percent As Decimal)

    m_salary =(1 + Percent) * m_salary

    End Sub

    Члени класу оголошуються з модифікаторами Public, Private або Friend. Ключове слово Pri vate означає, що член класу використовується тільки усередині класу.

    У класах іноді оголошуються закриті конструктори. «Яка користь від закритого конструктора?» — запитаєте ви. Конструктор оголошується закритим в тому випадку, якщо він викликається тільки самим класом виходячи з логіки його роботи.

    За умовчанням в VB .NET для класів і їх членів використовується рівень доступу Friend (доступ вирішується тільки з поточної програми). Втім, пропускати атрибути рівня доступу при оголошенні класу не рекомендується — особливо якщо врахувати, що рівень доступу, прийнятий за умовчанням, не є мінімальним.

    Атрибути рівня доступу і створення об'єктів

    Атрибути рівня доступу, встановлені для класу, управляють можливістю створення об'єктів відповідного типу. Грубо кажучи, вони є віддаленим аналогом властивості Instancing в Vb6, хоча для деяких значень Instancing доводиться додатково враховувати рівень доступу конструктора. У таблиці. 4.5 описана відповідність між властивістю Instancing Vb6 і комбінаціями атрибутів рівня доступу класу і конструктора.

    Таблиця 4.5. Значення властивості Instancing і атрибути рівня доступу

    Властивість Instancing Vb6

    Аналог в VB. NET

    Private Клас оголошується з атрибутом Private
    Publicnotcreatable Клас оголошується з атрибутом Public, але конструктор оголошується з атрибутом Friend
    Singlellse і Globalsingleuse Немає аналога в VB .NET
    Multiuse І клас, і конструктор оголошуються з атрибутом Public

    Me

    Якщо клас використовується як шаблон для створення однотипних об'єктів, програміст повинен мати можливість послатися на поточний об'єкт, якому належить виконуваний код. Зарезервоване слово Me завжди інтерпретується як об'єктна змінна, що позначає поточний екземпляр. Застосування Me гарантує, що неоднозначна конструкція буде інтерпретована в контексті поточного класу.

    Також варто відмітити, що один з найпоширеніших (і найбезглуздіших) прикладів використання Me зустрічається в ситуаціях на зразок наступної:

    Public Class Point

    Private x As Integer

    Private у As Integer

    Public Sub New(Byval x As Integer.ByVal у As Integer)

    Me.x = x

    Me.у = у End Sub

    ' І так далі

    End Class

    Запис Me. x використовується для того, щоб відрізнити поле х екземпляра від параметра х, передаваного при виклику методу New. Звичайно, проблема легко вирішується додаванням префікса m_ перед ім'ям змінної класу, проте подібні конструкції часто використовуються в С#; можливо, вони зустрінуться в програмі, супровід якої вам буде доручено.

    Перевантаження членів класу

    Метод Raisesalary класу Employee можна зробити і поцікавіше. Припустимо, підвищення зарплати до 10% відбуваються автоматично, але для великих сум потрібний спеціальний пароль. У колишніх версіях VB такі завдання вирішувалися за допомогою необов'язкових параметрів. Хоча ця можливість збереглася і в VB .NET, існує витонченіше рішення з визначенням двох версій Raisesalary. Використовуючи можливість перевантаження методів, ми визначаємо два разних методу для різних випадків.

    У VB .NET синтаксис перевантаження методів дуже простий: для цього в програмі просто визначаються два методи з однаковими іменами і різними параметрами. Проте ми настійно рекомендуємо використовувати ключове слово Over! oads. По ньому користувачі вашої коди дізнаються про те, що метод перевантажується навмисно, а не в результаті помилки. У наступному фрагменті приведено дві версії методу Raisesalary, про яких мовилося вище:

    Public Overloads Sub Raisesalary(Byval Percent As Decimal)

    If Percent > 0.1 Then

    ' Операція заборонена - необхідний пароль

    Console.WhteLineC'MUST HAVE PASSWORD TO RAISE SALARY " & _

    "MORE THAN 10*!!!!") Else X

    m_salary =(1 + Percent) * m_salary End If End Sub

    Public Overloads

    Sub Raisesalary(Byval Percent As Decimal._

    Byval Password As Stqng)

    If Password -"special Then

    m_salary = (1 + Percent) * m_salary

    End If End Sub

    При перевантаженні методи класу розрізняються тільки по типах параметрів. Методи не можуть перевантажуватися за типом повертаного значення або рівнем доступу.

    Нижче приведений приклад класу Empl oyee з переобтяженим методом Rai sesalany, а також невелика тестова програма. Звернете увагу: 10%-ний поріг не кодується в програмі, а визначається у вигляді константи:

    Option Strict On Module Modulel Sub Main()

    Dim Tom As New Employee("Tom". 100000)

    Console.WhteLineCTom.TheName & " has salary " & Tom.Salary)

    Tom.RaiseSalary(0.2d)

    ' Суфікс D - ознака типу Decimal

    Console.WriteLine(Tom.TheName & " still has salary " & Tom.Salary)

    Console. Whteline()

    Dim Sally As New Employee("Sally", 150000)

    Console.WriteLine(Sally.TheName & " has salary " & Sally.Salary)

    Sally.RaiseSalary(0.2d,"special")

    ' Суфікс D - ознака типу Decimal

    Console.WriteLine(Sally.TheName & "has salary "Ssally.Salary)

    Console. Writeline()

    Console.WriteLine("Please press the Enter key")

    Console. Readline()

    End Sub

    End Module

    Public Class Employee

    Private m_name As String

    Private m_salary As Decimal

    Private Const LIMIT As Decimal = 0.1d

    Public Sub New(Byval thename As String,byval cursalary As Decimal)

    m_name = thename

    m_salary = cursalary

    End Sub

    Readonly Property Thename()As String Get

    Return m_name

    End Get '

    End Property

    Readonly Property Salary()As Decimal Get

    Return m_salary

    End Get

    End Property

    Public Overloads

    Sub Raisesalary(Byval Percent As Decimal)

    If Percent > LIMIT Then

    ' Операція заборонена - необхідний пароль

    Console.WriteLine("MUST HAVE PASSWORD TO RAISE SALARY " & _

    "MORE THAN LIMIT!!!!")

    Else

    m_salary =(1 +Percent)*m_salary End If End Sub

    Public Overloads

    Sub Raisesalary(Byval Percent As Decimal._

    Byval Password As String)

    If Password = "special" Then

    m_salary =(1 + Percent) * m_salary

    End If

    End Sub

    End Class

    Знову про конструктори

    Якщо у вашому класі не визначений конструктор, VB .NET автоматично генерує для нього конструктор, що викликається без аргументів. Робота цього конструктора зводиться до ініціалізації всіх полів екземпляра значеннями за умовчанням. Такий конструктор називається конструктором за умовчанням або безаргумєїтн'м конструктором. Якщо в класі визначений хоч би один призначений для користувача конструктор, VB .NET не почне генерувати конструктор за умовчанням.

    Ніщо не заважає вам визначити в класі декілька конструкторів з різними рівнями доступу. Наприклад, можна визначити абсолютно безпечний конструктор з атрибутом Public і конструктор з атрибутом Friend, використання якого зв'язане з трохи більшим ризиком. Звичайно, ці конструктори повинні викликатися з різними параметрами, оскільки VB .NET розрізняє методи за списком параметрів, а не по модифікаторах рівня доступу.

    Конструктори перевантажуються, як і решта методів, проте при цьому не можна використовувати ключове слово Overloads. Нижче приведений фрагмент оновленої версії класу Employee з конструктором, що дозволяє задати значення нового поля.

    Public Class Employee

    Private m_name As String

    Private m_nickname As String

    Private m_salary As Decimal

    Public Sub Newcbyval sname As String.ByVal cursalary As Decimal)

    m_name = sname

    m_salary = cursalary

    End Sub

    Public SubNewcbyval thename As String.ByVal nickname As String._

    Byval cursalary As Decimal)

    m_name = thename

    m_nickname = nickname

    m_salary = cursalary

    End Sub

    Компілятор вибирає другу версію конструктора лише в тому випадку, якщо при виклику передаються два строкові параметри і один числовий. При передачі одного рядка і числа вибирається перший конструктор.

    Перевантаження конструкторів приводить до дублювання коди в програмі. Так, в приведеному вище фрагменті значення m_name і fli_sa,lary привласнювалися в обох конструкторах. У VB .NET для таких ситуацій передбачена спеціальна сокращенная запис: конструкція Myclass.New викликає інший конструктор класу [ На момент написання книги також можна було скористатися ключовим словом Me, але варіант з Myclass є переважним. ]. Приклад:

    Public Sub New(Byval sname As String.ByVal cursalary As Decimal)

    m_name = Sname

    mjsalary = cursalary End Sub

    Public Sub New(Byval sname As String, Byval nickname As String._ Byval cursalary As Decimal)

    Myclass.Newt sname.curSalary)

    m_nickname =nickName

    End Sub

    При виклику іншого конструктора конструкцією Myclass. New порядок визначення конструкторів в програмі не важливий. VB .NET вибирає конструктор за типом переданих параметрів незалежно від його місця у визначенні класу.

    Пам'ятаєте, що Myclass — ключове слово, а не об'єкт. Значення Myclass не можна привласнити змінній, передати процедурі або використовувати в операторові Is. У подібних ситуаціях використовується ключове слово Me; воно позначає конкретний об'єкт, код якого виконується зараз.

     




    :: Наша кнопка ::

    Отримати код:

    Підтримайте наш сайт і розмістіть нашу кнопку на своєму ресурсі.


    :: Реклама ::

    Скачати безкоштовно програму Microsoft Front Page 2003


    :: Посилання ::

    -


     

     

     


    Copyright ©