Попередня сторінка          Зміст           Наступна сторінка          Електронні посібники ВНТУ

 

ЛАБОРАТОРНА РОБОТА № 4

МЕТОДИ

 

 

Мета: навчитись працювати з методами, з’ясувати їх використання.

 

4.1 Теоретичні відомості

 

4.1.1 Методи

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

Зазвичай кожний додаток, що Ви розробили за допомогою Microsoft .NET Framework та C#, матиме багато методів, у кожного з яких є своя окрема мета. Деякі методи необхідні для функціонування додатка. Наприклад усі додатки, що розроблені на C# для персональних комп’ютерів, повинні мати метод з назвою Main. Цей метод слугує точкою входу в додаток. Коли користувач запускає такий додаток, CLR виконає метод Main в першу чергу.

Методи можуть бути розроблені для внутрішнього використання у класі та бути недоступними для інших класів. Існують також методи з ідентифікатором доступу public – це дозволить іншим класам звернутися до цього методу.

Взагалі .NET Framework складається з класів, що мають методи, які Ви можете викликати з Вашого додатку для взаємодії з користувачем чи з комп’ютером.

Для визначення методу нам потрібно описати метод та створити його тіло. Опис дозволяє нам визначити ідентифікатор доступу, тип даних, що метод буде повертати, назву методу та параметри. Тіло методу – це реалізація того функціоналу, що повинен мати метод.

Кожну частину опису можна пояснити так:

  • Ідентифікатор доступу – відповідає за доступність нашого методу (хто може викликати цей метод)
    • private – дозволяє викликати метод тільки всередині класу чи структури;
    • protected – дозволяє викликати цей метод з класу, де метод визначено та з похідних від нього;
    • public – дозволяє викликати цей метод з від усюди;
    • internal – дозволяє викликати цей метод всередині зборки;
    • static – визначає, що метод статичний член класу, а не член якогось об’єкта;
  • Тип даних, що повернеться – визначає, який тип даних буде повернуто. Якщо метод нічого не повертає, потрібно вказати void.
  • Назва метода – усі методи повинні мати назви, інакше ми не зможемо викликати їх.
  • Параметри – це список параметрів, що метод приймає у якості вхідних даних. Якщо параметрів декілька, їх треба розділити комою.

Приклад простого методу:

public Boolean StartService(string serviceName)

{

      //реалізація методи, що починає якийсь сервіс

}

У цьому прикладі public – ідентифікатор доступу, Boolean – тип даних, що буде повернуто, StartService – назва методу, string serviceName – параметр. Зверніть увагу, що параметр складається з типу даних та назви параметра.Declaring Methods

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

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

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

var uptime = 2000;

var shutdownAutomatically = true;

StartService(uptime, shutdownAutomatically);

//метод StartService

void StartService(int uptime, bool shutdownAutomatically)

{

      //реалізація методу

}

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

Наступний приклад покаже як отримати результат роботи методу GetServiceName присвоюючи його до змінної serviceName.

string serviceName = GetServiceName();

//метод GetServiceName

string GetServiceName()

{

      return “FourthCoffee.SalesService”;

}

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

  • Повернути масив чи колекцію
  • Використовувати ключове слово ref
  • Використовувати ключове слово out

У наступному прикладі ми викликаємо метод ReturnMultiOut. Параметри передаються з ключовим словом out. Це вказує на те, що змінні передається по “посиланню” і повинна бути визначена всередині методу. Зверніть увагу, що нам не потрібно призначати результат виконання цього методу до якоїсь змінної як у попередньому прикладі.

int first;

sting sValue;

ReturnMultiOut(out first, out sValue);

Console.WriteLine($“{first.ToString()}, {sValue}”);

static void ReturnMultiOut(out int i, out string s)

{

      i = 25;

      s = “using out”;

}

У наступному прикладі використовується ключове слово ref для того, щоб повернути декілька значень з методу. Зазвичай, ключове слово ref вимагає, щоб змінна була попередньо ініціалізована або вже використана.

sValue = string.Empty;

ReturnMultiRef(ref first, ref sValue);

Console.WriteLine($“{first.ToString()}, {sValue}”);

 

static void ReturnMultiRef(ref int I, ref string s)

{

      i = 50;

      s = “using ref”;

}

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

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

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

Наступний приклад покаже три версії методу StopService, усі з різними наборами параметрів.

void StopSerive()

{

      //ця версія не приймає жодних параметрів

}

void StopService(string serviceName)

{

//ця версія приймає параметр типу string

}

void StopService(int serviceID)

{

      //ця версія приймає параметр типу int

}

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

Одна з ключових особливостей C# це можливість працювати з додатками та компонентами, що розроблені з використанням іншим технології. Один з таких принципів, що використовується уWindows – Component Object Model, або просто COM. COM не підтримує перевантаження методів, але використовує методи, які можуть приймати необов’язкові параметри. Для простішої взаємодії з COM та компонентами, C# підтримує необов’язкові параметри.

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

Наступний приклад показує як створити метод, який приймає один обов’язковий параметр (forceStop) та два необов’язкових (serviceName, serviceID). Зверніть увагу, що механізм визначення необов’язкових параметрів вимагає значення за замовчуванням.

void StopService(bool forceStop, string serviceName = null, int serviceID = 1)

{

      //код

}

Ви можете викликати метод з необов’язковими параметрами так само як і інші методи. Потрібно вказати назву методу та забезпечити усі необхідні параметри. Різниця полягає в тому, що ви можете не назначувати необов’язкові параметри. У цьому випадку компілятор використає значення за замовчуванням.

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

У Visual C# Ви можете зазначати параметри за їх ім’ям і тому стає неважливим у якій послідовності Ви вказуєте їх. Для того, щоб використовувати іменовані параметри, Ви повинні вказати назву параметра та значення, розділивши їх двокрапкою.

Наступний приклад показує як викликати метод StopService використовуючи іменований параметр serviceID.

StopService(true, serviceID: 1);

Ви можете комбінувати позиційні та іменовані параметри за умови, що позиційні параметри завжди зазначені перед іменованими.

 

4.1.2 Обробка помилок

Вийняток – це ознака помилки або виняткової ситуації. Метод може створити виняток якщо буде знайдено щось несподіване, наприклад, додаток намагається відкрити файл, якого не існує в системі.

Коли метод створює вийняток, то код, що викликав цей метод, повинен бути готовим до обробки цього винятку(містити блок try/catch, про який буде сказано пізніше). Якщо цей код не готовий до оброки (наприклад, його немає), то код, що іде після виконання методу, що кинув виняток, буде скасований та виняток буде поширюватися вгору до тих пір, поки не знайдеться код, який зможете обробити цю помилку. Якщо не було знайдено такого коду, то виникне повідомлення для користувача та весь додаток закриється.

Ключова програмна конструкція, що дозволяє Вам реалізувати структурну обробку винятків у Вашому додатку – це блок try/catch. Вам потрібно огорнути код, що може створити виняток у блок tryта додати один чи декілька блоків catch для обробки винятків. Рекомендується спочатку обробляти більш специфічні помилки і тільки потім узагальнені. Наприклад, якщо Ви працюєте з файловою системою, краще спочатку обробити виняток FileNotFoundException (у першому блоці catch), а далі більш узагальнений виняток Exception, який спробує обробити будь-які винятки.

Наступний приклад показує як працювати з конструкцією try/catch.

try

{

      //Код, який може створити виняток

}

catch(FileNotFoundException ex)

{

      //Обробка, якщо не було знайдено файл

}

catch (Exception ex)

{

      //Обробка, якщо виникло щось несподіване

}

Інколи методи повинні складатися з коду, що повинен виконуватися завжди, навіть якщо є виняток. Наприклад, метод повинен переконатися, що файл буде закрито перед тим, як вивільняться ресурси. Блок finally дозволяє це зробити.

Цей блок потрібно визначати після усіх блоків catch у конструкції try/catch. Код у цьому блоці буде виконано незалежно від того, чи було все добре, чи були винятки, навіть якщо оброблені. Якщо буде створено виняток, то його обробка буде зроблена до того, як виконається код з блоку finally.

Ви також можете додати блок finally без визначення блоків catch. У цьому випадку, усі виключення залишаться необробленими, але код у блоці finally все одно буде виконано.

Наступний приклад покаже як використовувати конструкцію try/catch/finally.

try

{

}

catch (NullReferenceException ex)

{

}

catch (Exception ex)

{

}

finally

{

      //цей код виконається завжди

}

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

Для того, щоб поширити виняток використовуйте ключове слово throw та далі вкажіть об’єкт винятку.

Наступний код показує як створити виняток NullReferenceException та поширити його.

var ex = new NullReferenceException(“The ‘Name’ parameter is null”);

throw ex; 

Поширена стратегія – це намагатися спіймати та обробити будь-який виняток. Якщо обробник не може вирішити проблему, він може поширити виняток далі. Наприклад:

try {}

catch (NullReferenceException ex) {}

catch (Exception ex)

{

      //Намагаємося обробити, але не можемо. Поширюємо далі.

throw;

}

 

4.2 Завдання до лабораторної роботи (Додаток Г)

 

4.3 Контрольні запитання:

 

  1. Поняття методу.
  2. Різниця між простими і статичними.
  3. Оголошення методів.
  4. Параметри ref і out.
  5. Перевантаження методів.
  6. Змінне число параметрів методу.
  7. Віртуальні методи.
  8. підміна методів.
  9. Метод Main ().
  10. Використання методів в програмі.