:: Меню ::

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

    :: Друзі ::

     
     

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

    = =

     

     

     

     

    Інтерфейси

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

    Перш за все реалізацію інтерфейсу можна розглядати як контракт, обов'язковий для будь-якого класу. Інтерфейси займали найважливіше місце в програмуванні СОМ, а також в реалізації об'єктно-орієнтованих засобів в колишніх версіях VB. При реалізації інтерфейсу класс-обязуєтся надавати деяку функціональність відповідно до сигнатур заголовків членів відтепер і у віка століть. На відміну від об'єктів при спадкоємстві інтерфейси не зв'язані ніякими взаємними залежностями — кожна реалізація інтерфейсу існує незалежно від інших.

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

    Реалізація інтерфейсу припускає, що ваш клас містить методи із строго певними сигнатурами. Ці методи можуть бути порожніми, але вони обов'язково мають бути присутніми.

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

    • «розумний» компілятор може замінити виклики функцій швидким пошуком по таблиці з подальшою передачею управління;
    • з погляду програміста — розробники можуть викликати методи вашого класу по сигнатурі, не побоюючись, що вказаний метод не існує;
    • за наявності подібних зобов'язань компілятор може використовувати поліморфізм так само, як це робиться при спадкоємстві.

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

    А зараз подумайте, що відбудеться, якщо:

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

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

    1. Необхідно передбачити обробку помилок на випадок непередбачених ситуацій.
    2. Оскільки компілятор на стадії компіляції не може визначити, за якою адресою слід передати управління в блоці пам'яті, займаному об'єктом, йому доводиться покладатися на непрямі методи передачі управління на стадії виконання.

    Описаний процес називається пізнім скріпленням (late binding). Він не тільки значно поступається ранньому скріпленню за швидкістю, але і взагалі не дозволений при включеному режимі Option Strict за винятком пізнього скріплення, заснованого на застосуванні рефлексії.

    Механіка реалізації інтерфейсу

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

    У описаній вище ієрархії класів VB .NET визначити новий клас «провідний фахівець» не вдасться, оскільки класи Programmer і Tester вже є похідними від класу Empl oyee, а множинне спадкоємство в .NET не підтримується. Перед нами ідеальний приклад ситуації, коли вам на допомогу приходять інтерфейси.
    По загальноприйнятих правилах імена інтерфейсів в .NET починаються з прописною бук-ви «I», тому в наступному прикладі інтерфейс називається Ilead.

    Перш за все інтерфейс необхідно визначити. На відміну від Vb6, де інтерфейс був звичайним класом, в VB .NET з'явилося спеціальне ключове слово Interface. Припустимо, наші «ведучі» повинні оцінювати своїх підлеглих і витрачати засоби з фонду матеріального заохочення. Визначення інтерфейсу виглядає так:

    Public Interface Ilead

    Sub Spendmoralefund(Byval amount As Decimal)

    Function Rate(Byval aperson As Employee) As String

    Property Myteam() As Empl oyee ()

    Property Moralefuod() As Decimal End Interface

    Звернете увагу — у визначенні інтерфейсу відсутні модифікатори рівня доступу Publiс і Private. Дозволені тільки оголошення Sub, Function і Property з ключовими словами Overloads і Default. Як бачите, визначення інтерфейсу виглядає просто. Будь-який клас, що реалізовує інтерфейс Ilead, зобов'язується містити:

    • процедуру з параметром типу Decimal;
    • функцію, яка отримує об'єкт Empl oyee і повертає рядок;
    • властивість, доступна для читання і запису, повертає масив об'єктів Employee;
    • властивість, доступна для читання і запису, повертає значення типу Decimа1.

    Як буде показано нижче, імена методів реалізації неістотні — головне, щоб методи мали задану сигнатуру.

    Щоб реалізувати інтерфейс в класі, перш за все переконаєтеся в тому, що він сам або посилання на нього входить в проект. Далі за ім'ям класу і командою Inherits в програму включається рядок з ключовим словом Implements, за яким слідує ім'я інтерфейсу. Приклад:

    Public Class Leadprogrammer

    Inherits Programmer

    Implements Head

    End Class

    Ім'я Head підкреслюється синьою хвилястою межею, що свідчить про виниклу проблему. Тим самим компілятор наполягає на виконанні зобов'язань по реалізації інтерфейсу хоч би порожніми методами.

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

    Public Function Rate(Byval aperson As Employee) As String _

    Implements Ilead.Rate End Function

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

    Public Property Ourmoralefund() As Decimal Implements

    Head.MoraleFund Get

    Return m_moral e Fund

    End Get

    Set(Byval Value As Decimal)

    m_moralefund =Value

    End Set

    End Property

    Головне, щоб типи параметрів і повертаного значення відповідали сигнатурі даного члена інтерфейсу. При оголошенні методу можуть використовуватися будь-які допустимі модифікатори, що не заважають виконанню контракту, — Overloads, Overrides, Overridable, Public, Private, Protected, Friend, Protected Friend, Mustoverride, Default і Static. Забороняється тільки використовувати атрибут Shared, оскільки члени інтерфейсу повинні належати конкретному екземпляру, а не класу в цілому.

    Якщо в реалізації інтерфейсу використовується член класу з модифікатором Pri vate, звернення до цього члена можливі тільки через змінну, оголошену з типом даного інтерфейсу. На відміну від попередніх версій VB в решті випадків до членів інтерфейсу завжди можна звертатися через об'єкти класу. Тепер вам не доведеться привласнювати їх проміжним інтерфейсним змінним. Приклад:

    Dim tom As New Leadprogrammer("Tom",65000) tom.SpendMoraleFund(500)

    Проте в зворотних перетвореннях доводиться використовувати функцію Стуре:

    Dim tom As New Leadprogrammer("Tom". 65000)

    Dim alead As Ilead.aName As String

    alead = tom

    aname = Ctype(alead. Programmer).TheName 'OK

    Наступний рядок недопустимий:

    aname =tom.TheName ' ЗАБОРОНЕНО!

    Нижче перераховані загальні правила перетворення між типом об'єкту і інтерфейсом, ним що реалізовується.

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

    Щоб визначити, чи реалізує об'єкт деякий інтерфейс, скористайтеся ключовим словом Typeof у поєднанні з Is. Приклад:

    Dim torn As New Leadprogrammer("tom". 50000)

    Console.WriteLine((Typeof (tom) Is Head))

    Другий рядок виводить значення True.

    Один метод може реалізовувати декілька функцій, визначених в одному інтерфейсі:

    Public Sub itsok Implements

    Interface1.Ml.Interfacel.M2,Interfacel.M3

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

    Public Class Leadprogrammer

    Inherits Programmer Implements Head

    Private m_moralefund As Decimal

    Private m_myteam As Employee()

    Public Function Rate(Byval aperson As Employee) As String _

    Implements Head.Rate

    Return aperson.TheName & "rating to be done"

    End Function

    Public Property Myteam() As Employee()

    Implements Ilead.MyTeam

    Get

    Return m_myteam

    End Get

    Seubyval Value As Employee()) X.

    m_myteam = Value

    End Set End Property

    Public Sub Spendmoralefund(Byval

    amount As Decimal)_

    Implements Ilead.SpendMocaleFund

    ' Витратити засоби з фонду мат. заохочення

    Console.WriteLine("Spent " & amount.ToString())

    End Sub

    Public Property Ourmoralefund()As Decimal

    Implements Ilead.MoraleFund

    Get

    Return m_moralefund

    End Get

    Settbyval Value As Decimal)

    m_moralefund = Value

    End Set End Property

    Public Sub New(Byval thename As String. Byval cursalary As Decimal)

    Mybase.New(thename. cursalary)

    End Sub

    End Class

     




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

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

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


    :: Реклама ::

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


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

    -


     

     

     


    Copyright ©