- •Мови програмування. Представлення даних.
- •1. Вступ. Про обчислювальну техніку.
- •2. Історія мов програмування.
- •3. Поняття про платформу .Net
- •4. Створення мови програмування с#.
- •5. Представлення даних. Необхідність типізації. Двійкова арифметика.
- •6. Основні поняття програмування.
- •Поняття про інтегроване середовище розробки VisualStudio (на прикладі Visual Studio 2005). Структура c#-програми.
- •1. Основні можливості інтегрованого середовища розробки VisualStudio .Net.
- •2. Структура програми мовою с#.
- •Int I; // Визначили цілу змінну
- •Основні елементи мови с#.
- •1. Основні вбудовані типи мови с#
- •2. Визначення та ініціалізація змінних, область їх видимості.
- •3. Приведення типів.
- •Інакше обидва операнди перетворюються до типу int;
- •4. Літерали (константи) мови с#.
- •5. Операції мови с#.
- •5.1. Арифметичні операції.
- •5.2. Операції інкременту та декременту.
- •5.3. Операції відношення (порівняння).
- •5.4. Логічні операції.
- •5.5. Порозрядні (бітові) операції.
- •5.6. Умовна (тернарна) операція.
- •5.7. Операції присвоєння.
- •5.8. Пріоритет операцій.
- •Основні інструкції керування мови с# – розгалуження та цикли.
- •1. Розгалуження у мові с#
- •2. Цикли у мові с#
- •2.1. Цикл for.
- •2.2. Цикл while.
- •2.3. Цикл do-while.
- •3. Керування виходом із циклів с#
- •Масиви в мові с#.
- •1. Визначення та ініціалізація масиву.
- •2. Цикл foreach
- •3. Багатовимірні масиви.
- •4. Використання деяких методів класу System.Array.
- •5. Масиви масивів. Непрямокутні масиви.
- •Структуровані типи даних (колекції) в мові c#
- •1. Основні структури даних та їх призначення
- •2. Використання списку ArrayList та узагальненого списку List
- •3. Використання асоційованого списку Hashtable та узагальненого словника Dictionary
- •Класи в мові с#.
- •1. Визначення класу.
- •2. Методи класу.
- •3. Методи з параметрами.
- •4. Конструктор класу.
- •Методи в мові с#.
- •1. Передача об’єктів методам.
- •2. Використання модифікаторів для параметрів методів.
- •3. Методи, що повертають об’єкти.
- •Перевантаження методів в мові с#.
- •1. Перевантаження методів.
- •2. Перевантаження конструкторів.
- •3. Використання ключового слова this.
- •4. Деструктор класу.
- •5. Метод Main ().
- •Статичні члени класу.
- •1. Статичні дані-члени класу.
- •2. Статичні методи-члени класу.
- •3. Статичний конструктор класу.
- •4. Статичні класи, локалізація та глобалізація
- •Властивості та індексатори.
- •1. Властивості.
- •2. Індексатори.
- •Спадкування в мові с#.
- •1. Поняття про спадкування та ієрархію класів.
- •2. Спадкування та правила доступу до членів класів.
- •3. Конструктори базового та похідних класів.
- •4. Посилання на екземпляри базового та похідних класів.
- •5. Поняття про поліморфізм.
- •6. Віртуальні функції – більш детальний погляд.
- •7. Абстрактні методи та класи.
- •Перевантаження операцій в мові с#.
- •1. Загальні відомості.
- •2. Перевантаження бінарних арифметичних операцій.
- •3. Перевантаження унарних операцій.
- •4. Перевантаження операцій відношення.
- •5. Перевантаження логічних операцій.
- •6. Підсумкові зауваження.
- •Структури та переліки в мові с#.
- •1. Структури.
- •2. Переліки.
- •Делегати, події та обробники подій
- •1. Делегати (delegate).
- •2. Події та їх обробники.
- •Атрибути та їх використання
- •Рекомендована література
5. Поняття про поліморфізм.
Поліморфізм – наступний з трьох принципів ООП. Його застосування дозволяє створювати у похідних класах методи, які мають той самий інтерфейс, що й методи базового класу, проте відмінну функціональність.
Припустимо, що ми маємо клас BankAccount, що описує функціонування банківського рахунку. Крім звичайного банківського рахунку можна створити і інші – наприклад, депозитний рахунок DepositAccount, як похідний клас від BankAccount.
using System;
namespace BankAccount
{
class BankAccount // Це банківський рахунок
{
protected double money; // розмір вкладу
private long numAccount; // номер рахунку
// властивість - повертає розмір вкладу
public double Money
{
get { return money; }
}
// конструктор
public BankAccount(long numAccount_, double money_)
{
money = money_;
numAccount = numAccount_;
}
// поповнення рахунку
public void setMoney(long numAccount_, double sum)
{
if (numAccount_ != numAccount)
Console.WriteLine("Неправильний номер рахунку");
else money += sum;
}
// одержання грошей
public void getMoney(long numAccount_, double sum)
{
if (numAccount_ != numAccount)
Console.WriteLine("Неправильний номер рахунку");
else
if (money >= sum)
money -= sum;
else Console.WriteLine("Ви перевищили свій баланс");
}
// нарахування відсотків - бонус 6 %
public void setBonus()
{ money += money * 0.06; }
}
// Це депозитний банківський рахунок
class DepositAccount : BankAccount
{
private int termin; // термін депозиту
public DepositAccount(long numAccount_, double money_,
int termin_) : base (numAccount_, money_)
{ termin = termin_; }
}
class Program
{
static void Main()
{
// відкрили рахунок
BankAccount myBankAccount = new BankAccount(1, 1000);
Console.WriteLine("На рахунку - {0} грн.",
myBankAccount.Money);
myBankAccount.getMoney(1, 200); // зняли гроші
Console.WriteLine("На рахунку - {0} грн.",
myBankAccount.Money);
myBankAccount.setMoney(1, 200); // поповнили рахунок
Console.WriteLine("На рахунку - {0} грн.",
myBankAccount.Money);
myBankAccount.setBonus(); // одержали бонус
Console.WriteLine("На рахунку - {0} грн.",
myBankAccount.Money);
DepositAccount myDepositAccount =
new DepositAccount(1, 5000, 3);
Console.WriteLine("На депозитному рахунку - {0} грн.",
myDepositAccount.Money);
myDepositAccount.setBonus();
Console.WriteLine("На депозитному рахунку - {0} грн.",
myDepositAccount.Money);
}
}
}
В результаті роботи цієї програми на екрані одержимо такі повідомлення:
На рахунку – 1000 грн.
На рахунку – 800 грн.
На рахунку – 1000 грн.
На рахунку – 1060 грн.
На депозитному рахунку - 5000 грн.
На депозитному рахунку - 5300 грн.
Очевидно, що невірно нараховувати бонус однаковим чином по різних видах внесків на банківські рахунки. Отже, у кожному похідному класі необхідно мати для цього окремий метод. Зручно мати дійсно різні функції проте з ідентичним інтерфейсом. Досягти цього можна двома шляхами. Один з них можливий завдяки підтримці поліморфізму у мові С#. Ідея полягає у тому, що деякий метод базового класу може заміщатись у похідних класах. Таким чином, однакове звертання до екземплярів різних похідних класів призводить до різних відгуків – адже викликаються різні методи хоча й з однаковою сигнатурою. Це доволі складний механізм, і щоб підключити його підтримку, метод (або властивість) базового класу, який буде заміщатись у похідному класі, позначають службовим словом virtual. Відповідний метод у похідному класі позначають override:
class Base
{
public virtual void DoSomething() { }
public virtual int SomeProperty
{ get { return 0; } }
}
class SubBase : Base
{
public override void DoSomething () { }
public override int SomeProperty
{ get { return 0; } }
}
Інший шлях – визначити у похідному класі метод із модифікатором new, який буде перекривати (приховувати) відповідний метод базового класу. Тоді для екземплярів базового та похідних класів викликатимуться відповідно різні методи.
class Base
{
public void DoSomething () { }
public int SomeProperty
{ get { return 0; } }
}
class SubBase : Base
{
public new void DoSomething () { }
public new int SomeProperty
{ get { return 0; } }
}
Коли при визначенні члену класу використовується модифікатор new, цей новий член класу викликається замість відповідного члену базового класу, який виявляється перекритим. Тим не менше і перекритий член класу може бути викликаний, якщо екземпляр похідного класу приводиться до типу базового класу:
SubBase sb = new SubBase ();
sb.DoSomething (); // викликається новий метод
Base b = (Base)sb;
b.DoSomething (); // викликається старий метод
Зробимо поліморфним метод setBonus(). Для цього у базовому класі BankAccount змінимо його визначення наступним чином (з’являється службове слово virtual):
public virtual void setBonus() // бонус 6 %
{ money += money * 0.06; }
У похідному класі DepositAccount визначимо свій метод setBonus() із службовим словом override:
// бонус залежить від терміну
public override void setBonus()
{ money += money * 0.15 * termin / 4; }
Тепер звертання myDepositAccount.setBonus() означає виклик методу setBonus() похідного класу DepositAccount, а звертання myBankAccount.setBonus() – виклик однойменного методу базового класу BankAccount. Проте це ще далеко не всі можливості віртуальних функцій.