Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка - Основи Програмування C_.doc
Скачиваний:
46
Добавлен:
18.12.2018
Размер:
1.44 Mб
Скачать

2. Перевантаження конструкторів.

Оскільки конструктор – це метод класу, то конструктори також можуть перевантажуватись, отже, у класі можна визначити кілька конструкторів із різними списками параметрів. Це дозволяє створювати об’єкти класу по-різному в залежності від обставин. У наступному прикладі у класі Circle визначено 3 перевантажених конструктори: один ініціалізує своїми параметрами всі 3 дані-члени класу – координати x0, y0 центру кола та радіус r; другий має один параметр – значення радіусу, а центром кола вважається початок координат; нарешті, третій конструктор без параметрів взагалі – визначає коло одиничного радіусу із центром у початку координат. Визначення цього класу міститься в окремому файлі Circle.cs проекту.

using System;

namespace Overloading_Constructors

{

class Circle

{

double x0, y0; // координати центру кола

double r; // радіус кола

public Circle(double x0_, double y0_, double r_)

{ // Конструктор з трьома параметрами

x0 = x0_; y0 = y0_; r = r_;

Console.WriteLine("Створили коло - центр ({0};{1}),

радiус {2}", x0, y0, r);

}

public Circle(double r_)

{ // Конструктор з одним параметром

x0 = 0; y0 = 0; r = r_;

Console.WriteLine("Створили коло - центр ({0};{1}),

радiус {2}", x0, y0, r);

}

public Circle()

{ // Конструктор без параметрів

x0 = 0; y0 = 0; r = 1;

Console.WriteLine("Створили коло - центр ({0};{1}),

радiус {2}", x0, y0, r);

}

}

}

У файл Program.cs помістимо функцію Main , яка створює 3 екземпляри класу Circle з допомогою кожного з конструкторів. Зверніть увагу, що інструкцією Circle c1 = new Circle(); викликається не конструктор за замовчуванням, оскільки він взагалі не діє у цьому випадку – адже у класі існують власні конструктори – а саме написаний нами конструктор без параметрів.

using System;

namespace Overloading_Constructors

{

class Program

{

static void Main()

{

Circle c1 = new Circle();

Circle c2 = new Circle(10);

Circle c3 = new Circle(1, 2, 5);

}

}

}

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

Створили коло - центр (0;0), радiус 1

Створили коло - центр (0;0), радiус 10

Створили коло - центр (1;2), радiус 5

Таким чином, всі три об’єкти класу були створені різними конструкторами. Можливість перевантаження конструкторів надає гнучкості при створенні екземплярів. Ще більшого ефекту можна досягти, використовуючи можливість виклику одного конструктору іншим.

3. Використання ключового слова this.

Ключове слово this у методі класу означає посилання на поточний екземпляр, тобто той, для якого був викликаний даний метод. Пригадаємо визначення класу Polar_Point . Він містив методи, що визначають декартові координати даної полярної точки. Наведемо ще раз тут окремо визначення цих методів:

public double xCoord() // абсциса полярної точки

{

return r * Math.Cos(phi);

}

public double yCoord() // ордината полярної точки

{

return r * Math.Sin(phi);

}

Обидва методи безпосередньо звертаються до членів класу r та phi без вживання складених імен, що включають ідентифікатори класу або екземпляру. Проте у тих самих методах можна використати посилання this , щоб підкреслити що використовуються дані-члени даного поточного екземпляру класу:

public double xCoord() // абсциса полярної точки

{

return this.r * Math.Cos(this.phi);

}

public double yCoord() // ордината полярної точки

{

return this.r * Math.Sin(this.phi);

}

Тоді, якщо у функції Main був створений екземпляр p1 класу Polar_Point

Polar_Point p1 = new Polar_Point();

то виклик методу p1.xCoord() або p1.yCoord() фактично означає, що значенням this є посиланням на екземпляр p1 , тобто this.r це p1.r , а this.phi це p1.phi. Зазвичай посилання this не використовується таким чином – у цьому просто немає необхідності.

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

public Polar_Point(double r, double phi)

{

// Конструктор – формальні параметри мають ті самі

// ідентифікатори, що й члени класу

this.r = r; this.phi = phi;

}

Якби тут не було використано посилання this , то формальні параметри конструктора double r, double phi перекривали б члени класу Polar_Point з такими самими ідентифікаторами, і не було б можливості їх проініціалізувати вказаними значеннями.

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

<специфікатор_доступу> <ідентифікатор_класу>

(<список_параметрів_конструктора_1>) :

this (<список_параметрів_конструктора_2>)

{

// код конструктора

}

Якщо об’єкт класу створюється таким конструктором, то спочатку викликається той конструктор класу, який має список параметрів, відповідний до <списку_параметрів_конструктора_2> з урахуванням приведення типів, а лише потім виконується код початкового конструктора, який може бути і порожнім взагалі. В цій синтаксичній конструкції this (<список_параметрів_конструктора_2>) називається ініціалізатором конструктору.

Повернемось до прикладу Overloading_Constructors, в якому визначається клас Circle . Файл Circle.cs змінимо наступним чином:

using System;

namespace Overloading_Constr_this

{

class Circle

{

public double x0, y0; // координати центру кола

public double r; // радіус кола

public Circle(double x0_, double y0_, double r_)

{ // Конструктор з трьома параметрами

x0 = x0_; y0 = y0_; r = r_;

Console.WriteLine("Створили коло - центр ({0};{1}),

радiус {2}", x0, y0, r);

}

public Circle(double r_) : this (0, 0, r_)

{ // Конструктор з одним параметром }

public Circle() : this(0, 0, 1)

{ // Конструктор без параметрів }

}

}

Зверніть увагу, що тут єдиним «діючим» конструктором є конструктор Circle(double x0_, double y0_, double r_), адже два інших конструктори не роблять нічого, просто звертаються через this саме до нього, вказуючи потрібні набори параметрів для ініціалізації.

Якщо у в основному файлі проекту записати наступний код

using System;

namespace Overloading_Constr_this

{

class Program

{

static void Main()

{

Circle c1 = new Circle();

Circle c2 = new Circle(10);

Circle c3 = new Circle(5, 4, 3);

}

}

}

то після запуску прикладу на виконання на екрані побачимо наступний результат:

Створили коло - центр (0;0), радiус 1

Створили коло - центр (0;0), радiус 10

Створили коло - центр (5;4), радiус 3

При створенні всіх цих об’єктів викликались 3 різних конструктори, проте повідомлення про створення кола, насправді надсилав лише один з них, до якого два інших звертались завдяки посиланню this.