Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LR_3_Robota_z_polimorfnimi_klasami_ta_interfey.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
102.36 Кб
Скачать

2.1.3 Методи, які розширюють існуючі класи

Іноді виникає потреба в додаванні до раніше створених класів нових методів. Традиційно є три шляхи розв'язання цієї проблеми:

  • модифікація вихідного коду. Звичайно, такий підхід не можна вважати коректним. Крім того, іноді модифікація вихідного коду взагалі неможлива, наприклад, коли йдеться про стандартні класи та структури .NET Framework, або взагалі, коли ми використовуємо класи, які надані у скомпільованому вигляді;

  • створення похідного класу, до якого додаються необхідні методи. Цей підхід має чисельні обмеження. Наприклад, перевантажені операції не можуть бути застосовані до об'єктів похідних класів, отже відповідні операторні функції необхідно визначати знову. Крім того, похідні класи не є частиною бібліотеки класів .NET Framework і для їх імен не можна створити ключові слова C#, як, наприклад, string. Але найважливішим є те, що структури не підтримують механізму спадкування;

  • створення власних статичних функцій з параметром типу об'єкта класу, який ми хочемо розширити. Це цілком коректний підхід, але він пов'язаний з деякими незручностями. Зокрема, поза класом, у якому визначені ці функції, необхідно вживати відповідний префікс.

Версія 3.0 мови C# надає можливість додавання нових методів до існуючих класів та структур. Для додавання нового метода (наприклад, з ім'ям newMethod) необхідно виконати наступні дії:

  • створити статичний клас

  • додати новий статичну функцію newMethod, першим параметром якого буде посилання на об'єкт типу (класу або структури), до якого ми хочемо додати новий метод; перед описом параметру слід додати модифікатор this.

Тепер всередині поточного простору імен можна вживати функцію як нестатичний метод об'єкта відповідного типу. Наприклад, можна розширити стандартний тип int функцією, яка потроює відповідне ціле значення. Створюємо новий статичний клас:

namespace Extensions

{

public static class IntExtensions

{

public static int Triple(this int k)

{

return k * 3;

}

}

}

Можна викликати метод Triple() як для змінних, так і для констант відповідного типу:

int n = 2;

int m = n.Triple();

int k = 9.Triple();

Функцію Triple() можна також викликати як статичну:

int q = IntExtensions.Triple(m);

Видимість методу Triple() обмежена поточним простором імен. За допомогою директиви using розширення можна зробити приступними в інших просторах імен.

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

public static class DoubleExt

{

public static double add(this double a, double b)

{

return a + b;

}

}

class Program

{

static void Main(string[] args)

{

double x = 2.5.add(3);

Console.WriteLine(x); // 5.5

}

}

6 Перевантаження операцій

Під час проектування класу можна визначити набір операцій, які можна виконувати над об'єктами. До операцій, що перевантажуються, належать унарні операції +, -, !, ~, ++, --, truefalseі бінарні +, -, *, /, %, &, |, ^, <<, >>, ==, !=, <, >, <=, >=. Якщо для об'єкта перевантажені операції true і false, посилання на нього може бути використане у якості аргументів умовної операції, іf і циклів. Операції true і false, == і !=, > і <, >= і <= є парними: якщо в класі перевантажується одна з них, обов'язково повинна бути перевантажена й інша.

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

Функції explicit operator Ім'я_типу() і implicit operator Ім'я_типу() використовуються для явних і неявних перетворень типів відповідно. Неявні перетворення в C# відповідають спеціальним операторам перетворення (випадок перетворення з класу в інший тип) і конструкторам з одним параметром (випадок перетворення з іншого типу в даний клас).

У наступному класі перевантажується операція + і операція неявного приведення до типу string:

using System;

namespace PointTest

{

class Point

{

private double x, y;

public Point(double x, double y)

{

this.x = x;

this.y = y;

}

public static Point operator+(Point a, Point b)

{

return new Point(a.x + b.x, a.y + b.y);

}

public static implicit operator string(Point p)

{

return p.x + " " + p.y;

}

}

class Test

{

static void Main(string[] args)

{

Point p1 = new Point(1, 2);

Point p2 = new Point(3, 4);

Point p3 = p1 + p2;

Console.WriteLine(p3); // Приведення до string

}

}

}

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]