:: Меню ::

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

    :: Друзі ::

     
     

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

    = =

     

     

     

     

    Загальні члени класів

    Закриті загальні поля класів у поєднанні з ReadOnly-свойствами дуже зручні, але цим сфера застосування ключового слова Shared не вичерпується. У класі можна оголошувати загальні властивості і методи. Як було показано на прикладі класу Math, при зверненні до загальних засобів класу указується або ім'я класу, або ім'я конкретного екземпляра. Допустимо, в клас Employee включається загальна функція Calcul atefica, залежна від двох відкритих констант:

    Public Const Fica_limit As Integer = 76200

    Public Const Fica_percentage As Decimal = 0.062d

    Функція CALCULATEFICA виглядає так:

    Public Shared Function CALCULATEFICA(Byval asalary As Decimal) As Decimal

    If asalary > Fica_limit Then

    Return Fica_limit * Fica_percentage

    Else

    Return asalary * Fica_percentage

    End If

    End Function

    Загальні члени класу можуть використовуватися без створення екземплярів Empl oyee, тільки по імені класу. Приклад:

    System.Console.WriteLine(Employee.

    CALCULATEFICA(100000))

    З іншого боку, метод мджно викликати і для конкретного екземпляра Employee:

    System.Console.WriteLine

    (Tom.CalculateFICA

    (Tom.GetSalary())

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

    New включається ключове слово Shared. Загальні конструктори:

    • не володіють атрибутами Publiс або Private;
    • викликаються без параметрів;
    • можуть працювати тільки із загальними полями класу. Як правило, загальні конструктори застосовуються тільки для ініціалізації загальних даних. Код загального конструктора виконується при створенні першого екземпляра вказаного класу, перед викликом решти всіх конструкторів.

    Життєвий цикл об'єкту

    Отже, при створенні екземпляра класу оператором New викликається відповідний метод-конструктор New з визначення класу (також може бути викликаний загальний конструктор, якщо він є). Версія конструктора вибирається відповідно до типу переданих параметрів. Конструктор можна розглядати як аналог події Class_initiall ze в Vb6.

    Не у кожному класі визначається відкритий конструктор. Більш того, в деяких ситуаціях всі конструктори класу оголошуються закритими і екземпляри створюються тільки загальними методами. Конструктор оголошується закритим в одному з наступних випадків:

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

    Після того, як об'єкт буде створений оператором New, ви не зможете змінити його стан повторним викликом New. Приклад:

    Dim Tom As New Employeec'tom ", 100000)

    Tom = New Employee("Tom ". 125000)

    У цьому фрагменті створюються два разних об'єкту Empl oyee, причому після привласнення в другому рядку перший об'єкт Той втрачається. Іноді це відповідає намереніям програміста, іноді — ні. Наприклад, якщо ідентифікатор працівника зберігається в загальній змінній Empl oyeeid, то другий рядок привласнить другому об'єкту Той ідентифікатор на 1 більше первинного. Так або інакше, наступний фрагмент свідомо неможливий:

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

    Dim Tom As New Employee("Tom ", 125000)

    Компілятор видає наступне повідомлення про помилку:

    The local variable 'Tom' is defined multiple times in the same method.

    Знищення об'єктів

    У VB .NET об'єкти не вмирають «природною смертю»; у якомусь сенсі вони поступово «сходять у небуття» з часом. Головна відмінність від попередніх версій VB полягає в тому, що ви не можете явно звільнити пам'ять, займану об'єктом. Вбудований складальник сміття коли-небудь відмітить, що ці блоки пам'яті не використовуються в програмі, і автоматично звільнить їх. Автоматична збірка сміття робить сильний вплив на програмування в VB .NET. Зокрема, збірку сміття слід розглядати як повністю автоматизований процес, на який ви абсолютно не можете вплинути.

    Хоча в програмі можна провести примусову збірку сміття викликом методу System. GC. Collect(), вважається, що це не відповідає хорошому стилю програмування .NET. Ми рекомендуємо завжди покладатися на автоматичну збірку сміття.

    Пригадаєте, що в колишніх версіях VB в кожному класі існувала подія Termi nate, яке гарантовано викликалося в той момент, коли кількість посилань зменшувалася до 0 (у термінології ООП це називається детермінованим завершенням). У VB .NET (як би ви до цього не відносилися) підтримується тільки недетерміноване завершення, з чого виходить, що ви не можете розраховувати на те, що якийсь аналог події Termi nate буде викликаний в певний момент часу. Більш того, не гарантовано навіть те, що він взагалі буде коли-небудь викликаний!

    Деякі програмісти вважають Finalize за аналог події Terminate в VB .NET, проте ця аналогія невірна. Метод Finalize всього лише містить код, який повинен виконуватися при звільненні пам'яті вашого об'єкту в процесі збірки сміття. Але оскільки ви не можете явно управляти тим, коли це відбудеться, ми настійно рекомендуємо використовувати Finalize лише як додатковий захід безпеки — наприклад, для дублювання методу Dispose, який повинен викликатися користувачем класу. Метод Dispose розглядається нижчим.

    Виникає питання: якщо раніше ми проводили дєїніциалізацию класу в події Terminate, як же це робиться зараз? Для вирішення цієї проблеми в VB .NET існує дуже важливе правило:

    Якщо ваш клас повинен звільняти які-небудь зовнішні ресурси, окрім звичайної пам'яті (наприклад, підключення до бази даних, графічні контексти, файлові маніпулятори і т.. д.), він повинен містити метод з ім'ям Di spose, що викликається із зовнішньої коди.

    Ми повернемося до методу Dispose при розгляді інтерфейсу Idisposabl e в розділі 5. А поки досить сказати, що будь-яке графічне застосування — навіть найпростіше, на зразок продемонстрованого в розділі 1, — відноситься до категорії програм, в яких необхідний метод Dispose. Це пов'язано з тим, що графічні програми захоплюють так звані графічні контексти, які мають бути звільнені для повернення ресурсів в систему (графічні контексти не є блоками пам'яті, тому автоматична збірка сміття в даному випадку не допоможе). Тепер стає ясно, чому в код, що автоматично згенерував, приведений в розділі 1, входить виклик Dispose. Недетерміноване завершення належить до самих неоднозначних нововведень .NET, проте автоматична збірка сміття є невід'ємною частиною .NET. Розробникам за всього бажання не вдалося б зберегти колишній, детермінований варіант управління пам'яттю і забезпечити сумісність .NET. Крім того, механізму, використаному в старих версіях VB (підрахунок посилань), властиві проблеми з витоком пам'яті, викликаної існуванням циклічних посилань, коли об'єкт А посилається на об'єкт В і навпаки, як показано на мал. 4.8.

    Такі мови, як Java, наочно довели, що переваги від автоматичної збірки сміття виправдовують невеликі зміни в стилі програмування, пов'язані з відсутністю детермінованого завершення.

    Мал. 4.8. Два різновиди циклічних посилань

    Структурні типи

    Традиційно в об'єктно-орієнтованих мовах виникали немало проблем з простими типами даних — такими, як звичайні цілі числа. Річ у тому, що в об'єктно-орієнтованій мові всі дані мають бути об'єктами. З іншого боку, створення об'єкту зв'язане з певними витратами на виконання службових операцій (таких, як виділення блоку пам'яті для об'єкту). Обробка повідомлення «скласти» також поступається за швидкістю простою математичній операції складання і так далі Варто додати, що в мовах з автоматичною збіркою сміття якийсь час витрачається на знищення невживаних об'єктів.

    Ранні об'єктно-орієнтовані мови пішли по найпрямолінійнішому шляху. Скажімо, в Smalltalk всі дані інтерпретувалися як об'єкти. В результаті такі мови працювали повільніше, ніж мови з розділенням примітивних типів і об'єктів. З іншого боку, подібне розділення приводило до ускладнення програм, оскільки програмний код, що працював з числами, доводилося відокремлювати від коди, що працювала з об'єктами. Щоб інтерпретувати число в об'єктному контексті, його доводилося «завертати» в об'єкт. Наприклад, в Java збереження числа в еквіваленті динамічного масиву виглядало приблизно так:

    anarraylist.Add(Integer(5));

    Число 5 «заверталося» в об'єкт Integer. Такі програми погано читалися і поволі працювали.

    У .NET Framework були об'єднані кращі сторони обох рішень. У загальному випадку числа інтерпретуються як примітивні типи, але при необхідності вони автоматично інтерпретуються як об'єкти. Таким чином, для звичайного числового літерала можна викликати метод або занести його в хэш-таблицу без додаткових зусиль. Це називається автоматичною упаковкою (boxing); зворотний процес називається розпаковуванням (unboxing).

    Для нас, програмістів, з цього витікає важливе слідство: хоча в VB .NET всі дані є об'єктами, не кожна змінна в програмі містить маніпулятор блоку пам'яті і створюється оператором New. Зрозуміло, ніщо не дається дарма: програмістові доводиться пам'ятати про відмінності між структурними і посилальними типами. Перше, найбільш очевидна відмінність полягає в тому, що нові екземпляри структурних типів створюються без ключового слова New. Вам не доведеться (та і не вдасться) використовувати конструкції виду Dim а As New Integer(5).

    Серйозніша відмінність пов'язана з передачею змінних процедурам за значенням. Як було сказано вище, при передачі змінного об'єкту за значенням процедура може змінити стан об'єкту. Передані за значенням структурні типи поводяться цілком традиційно — всі зміни втрачаються при виході з викликаної процедури або функції (іноді це називається структурною семантикою на відміну від посилальної семантики).

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

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

    Function Isvaluetype(Byval foo As Object) As Boolean

    If Typeof (foo) Is System.ValueType Then

    Return True Else

    Return False

    End If

    End Function

    Для об'єктів структурного типу оператора Equal s завжди повертає True, якщо структурні об'єкти містять однакові дані. Синтаксис виклику виглядає так:

    а..Fquals(b)

    Врахуйте, що для посилальних типів цей принцип в загальному випадку не виконується. Наприклад, два масиви можуть містити однакові елементи, але рівними при цьому вони не вважаються.

    У VB .NET структурні типи діляться на дві категорії: структури і перераховувані типи. Ми почнемо з перераховуваних типів, а потім перейдемо до структур, які є «полегшеними» варіантами об'єктів.

    Перераховувані типи

    Перераховувані типи зазвичай використовуються для визначення набору іменованих цілочисельних констант. При визначенні перераховуваного типу використовується пара ключових слів Enum-end Enum разом з модифікатором доступу. Перераховуваний тип може містити тільки цілочисельні типи ніби Integer або Long (тип Char недопустимий). Наприклад, в наступному фрагменті визначається відкритий перераховуваний тип з ім'ям Bonusstructure:

    Public Enum Bonusstructure

    None = 0

    Firstlevel = 1

    Secondlevel = 2

    End Enum

    Після цього в будь-якому місці програми можна оголосити змінну типу Bonusstructure: Dim bonuslevel As Bonusstructure

    При роботі з перераховуваними типами, як і з іншими структурними типами, ключове слово New не використовується.

    Якщо в перераховуваному типі вказані тільки імена без числових значень .NET начи-наєт відлік з 0 і збільшує значення на 1 для кожної нової константи. Якщо задано тільки перше число, то кожне наступне значення обчислюється збільшенням попереднього на 1.

    Визначивши в проекті перераховуваний тип, ви можете використовувати конструкції вигляду

    Bonus =Tom.Sales * bonuslevel.SecondLevel

    Оскільки перераховувані типи неявно інтерпретуються як загальні, в посиланнях на них можна указувати ім'я перераховуваного типу замість імені змінної:

    Public Function Calcu1atebonus(Byval thesales As Decimal) As Decimal

    Return thesales * Bonusstructure.SecondLevel

    End Function

    Одним з традиційних недоліків перераховуваних типів була відсутність зручних засобів для отримання імені за значенням, що утрудняло відладку програм. У класі Enum, базовому для всіх перераховуваних типів, визначені дуже корисні методи для отримання подібної інформації. Наприклад, наступна команда повертає рядок Firstlevel :

    Bonusstructure.GetName(bonuslevel .GetType.l)

    Даний фрагмент виводить всі імена, що входять в перераховуваний тип:

    Dim enumnames As String().s As String

    enumnames = Bonusstructure.GetNames(bonuslevel.GetType)

    For Eachs In enumnames

    System.Console.WriteLine(s) Next

     




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

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

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


    :: Реклама ::

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


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

    -


     

     

     


    Copyright ©