Конструктор призначений для ініціалізації об'єкту. Він викликається автоматично при створенні об'єкту класу за допомогою операції new. Ім'я конструктора збігається з ім'ям класу. Нижче перераховані властивості конструкторів:
§ Конструктор не повертає значення, навіть типу void.
§ Клас може мати декілька конструкторів з різними параметрами для різних видів ініціалізації.
§ Якщо програміст не вказав жодного конструктора або якісь поля не ініціалізовані, полям значущих типів привласнюється нуль, полям посилальних типів - значення null.
§ Конструктор, що викликається без параметрів, називається конструктором за умовчанням.
До цих пір ми задавали початкові значення полів класу при описі класу (лістинг 5.1). Це зручно у тому випадку, коли для всіх екземплярів класу початкові значення деякого поля однакові. Якщо ж при створенні об'єктів потрібно привласнювати полю різні значення, це слід робити в конструкторі. У лістингу 5.6 в клас Demo доданий конструктор, а поля зроблені закритими (непотрібні в даний момент елементи відсутні). У програмі створюються два об'єкти з різними значеннями полів.
Лістинг 5.6. Клас з конструктором
using System;
namespace ConsoleApplicationl
{
class Demo
{
public int a = 1 ;
public const double с = 1.66;
double y;
public Demo( int a, double y ) // конструктор з параметрами
{
this.a = a;
this.y = y;
}
public double Gety( ) // метод отримання поля у
{
return y;
}
}
class Classl
{
static void Main( )
{
Demo a = new Demo( 300, 0.002); // виклик конструктора
Console.WriteLine (a.Gety( )); // результат: 0,002
Demo b = new Demo(1,5.71 ); // виклик конструктора
Console.WriteLine( b.Gety( ) ); // результат: 5,71
}
}
}
Часто буває зручно задати в класі декілька конструкторів, щоб забезпечити можливість ініціалізації об'єктів різними способами. Приклад:
class Demo
{
public Demo( int a ) // конструктор 1
{
this.a = a;
this.у = 0.002;
}
public Demo( double у ) // конструктор 2
{
this.a = 1;
this.у = у;
}
…
}
…
Demo x = new Demo( 300 ); // виклик конструктора 1
Demo у = new Demo( 5.71 ); // виклик конструктора 2
Всі конструктори повинні мати різні сигнатури.
Якщо один з конструкторів виконує які-небудь дії, а інший повинен робити те ж саме плюс ще що-небудь, зручно викликати перший конструктор з другого. Для цього використовується вже відоме вам ключове слово this в іншому контексті, наприклад:
class Demo
{
public Demo( int a ) // конструктор 1
{
this.a = a;
}
public Demo( int a, double у ) : this(a) // виклик конструктора 1
{
this.у = у;
}
…
}
Конструкція, що знаходиться після двокрапки, називається ініціалізатором, тобто тим кодом, який виконується до початку виконання тіла конструктора.
Як ви пам'ятаєте, всі класи в С# мають загального предка - клас object. Конструктор будь-якого класу, якщо не вказаний ініціалізатор, автоматично викликає конструктор свого предка. Це можна зробити і явним чином за допомогою ключового слова base, що позначає конструктор базового класу. Таким чином, перший конструктор з попереднього прикладу можна записати і так:
public Demo( int а ) : base( ) // конструктор 1
{
this.а = а;
}
Конструктор базового класу викликається явним чином в тих випадках, коли йому потрібно передати параметри.
До цих пір мова йшла про “звичайні ” конструктори, або конструктори екземпляра. Існує другий тип конструкторів - статичні конструктори, або конструктори класу. Конструктор екземпляра ініціалізував дані екземпляра, конструктор класу - дані класу.
У класі, що складається тільки із статичних елементів (полів і констант), описувати статичний конструктор не обов'язково, початкові значення полів зручніше задати при їх описі.
В лістингу 5.7 приведений приклад статичного класу.
Лістинг 5.7. Статичний клас
using System;
namespace ConsoleApplicationl
{
static class D
{
static int a = 200;
static double b = 0.002;
public static void Print ( )
{
Console.WriteLine("a="+a);
Console.WriteLine("b="+b);
}
}
class Classl
{
static void Main( )
{
D.Print( );
}
}
}
Як приклад, на якому демонструватиметься робота різними елементами класу, створимо клас Monster, моделюючий персонаж комп'ютерної гри. Для цього потрібно задати його властивості (наприклад, кількість щупальців, силу або наявність гранатомета) і поведінку. Опис класу Monster приводиться на лістингу 5.8.
Лістинг 5.8. Клас Monster
using System;
namespace ConsoleApplication1
{
class Monster
{
public Monster( )
{
this.name = "Noname";
this.health = 100;
this.ammo = 100;
}
public Monster(string name) : this( )
{
this.name = name;
}
public Monster( int health, int ammo, string name )
{
this.name = name;
this.health = health;
this.ammo = ammo;
}
public string GetName( )
{
return name;
}
public int GetHealth( )
{
return health;
}
public int GetAmmo( )
{
return ammo;
}
public void Passport( )
{
Console.WriteLine( "Monster {0} \t health = {1} ammo = {2}",
name, health, ammo );
}
string name; // закриті поля
int health, ammo;
}
class Classl
{
static void Main()
{
Monster X = new Monster( );
X.Passport( );
Monster Vasia = new Monster("Vasia");
Vasia.Passport( );
Monster Masha = new Monster(200, 200, "Masha" );
Masha.Passport( );
}
}
}
Результат роботи програми:
Monster Noname health = 100 ammo = 100
Monster Vasia health = 100 ammo = 100
Monster Masha health = 200 ammo = 200
У класі три закриті поля (name, health і ammo), чотири методи (Getname, Gethealth, Getammo і Passport) і три конструктори.