Деструкторы
Конструкторы.
Конструктор предназначен для инициализации объекта. Он вызывается автоматически при создании объекта класса с помощью операции new. Имя конструктора совпадает с именем класса.
Свойства конструкторов:
- конструктор не возвращает значение, даже типа void;
- класс может иметь несколько конструкторов с разными параметрами для разных видов инициализации;
- если программист не указал ни одного конструктора или какие-то поля не были инициализированы, полям значимых типов присваивается нуль, полям ссылочных типов – значение null;
- конструктор, вызываемый без параметров, называется конструктором по умолчанию.
сlass Demo
{
Public Demo (int a, double y) // Конструктор с параметрами
{
this.a = a;
this.y = y;
}
Public double Gety() // Метод получения поля y
{
return y;
}
int a;
double y;
}
сlass Class1
{
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.y = 0.002;
}
public Demo(double y) // Конструктор 2
{
this.a = 1;
this.y = y;
}
Demo x = new Demo(300); // вызов конструктора 1
Demo y = new Demo(5.71); // вызов конструктора 2
Если один конструктор выполняет какие-либо действия, а другой должен делать то же самое плюс еще что-нибудь, удобно вызвать первый конструктор из второго. Для этого используется ключевое слово this в другом контексте.
сlass Demo
{
public Demo(int a) // Конструктор 1
{
this.a = a;
}
public Demo(int a, double y) : this(a) // Вызов конструктора 1
{
this.y = y;
}
}
Статические конструкторы, или конструкторы класса – не имеет параметров, его нельзя вызвать явным образом. Система сама определяет момент, в который требуется его выполнить. Гарантируется только, что это происходит до создания первого экземпляра объекта и до вызова любого статического метода.
Некоторые классы содержат только статические данные, и, следовательно, создать экземпляры таких объектов не имеет смысла.
class D
{
private D(){} // закрытый конструктор
static D() // статический конструктор
{
a = 200;
}
static int a;
static double b = 0.002;
public static void Print()
{
Console.WriteLine(“a=” + a);
Console.WriteLine(“b=” + b);
}
}
Средства языка C# позволяют определить метод, который должен вызываться непосредственно перед тем, как объект будет окончательно разрушен системой сбора мусора. Этот метод называется деструктором, и его можно использовать для обеспечения гарантии “чистоты” ликвидации объекта. Например, вы могли бы использовать деструктор для гарантированного закрытия файла, открытого некоторым объектом. Формат записи деструктора такой:
~имя_класса()
{ // код деструктора }
Очевидно, что элемент имя_класса здесь означает имя класса. Таким образом, деструктор объявляется подобно конструктору за исключением того, что его имени предшествует символ “тильда” (~). (Подобно конструктору, деструктор не возвращает значения).
Деструкторы будут вызваны перед завершением программы. Использование деструктора демонстрируется в следующей программе, которая создает и разрушает большое количество объектов. В определенный момент выполнения этого процесса будет активизирован сбор мусора, а значит, вызваны деструкторы разрушаемых объектов.
// Демонстрация использования деструктора.
using System; class Destruct
{
public int x; public Destruct(int i) { x = i; } // Вызывается при утилизации объекта.
~Destruct()
{
Console.WriteLine("Деструктуризация " + x);
} // Метод создает объект, который немедленно
// разрушается.
public void generator(int i)
{
Destruct о = new Destruct(i);
}
}
class DestructDemo
{
public static void Main()
{
int count; Destruct ob = new Destruct(0); /* Теперь сгенерируем большое число объектов. В какой-то момент начнется сбор мусора. Замечание: возможно, для активизации этого процесса вам придется увеличить количество генерируемых объектов. */
for(count = 1; count < 100000; count++)
ob.generator(count);
Console.WriteLine("Готово!");
}
}
Вот как работает эта программа. Конструктор устанавливает переменную экземпляра x равной известному числу. В данном примере x используется как ID (идентификационный номер) объекта. Деструктор отображает значение переменной x при утилизации объекта. Рассмотрим метод generator(). Он создает объект класса Destruct, а затем разрушает его с уведомлением об этом.
Контрольные вопросы по теме «Классы»:
1. Что называется классом?
2. Синтаксис объявления класса.
3. Перечислить элементы класса.
4. Что определяет свойство класса.
5. Какие спецификаторы допускаются для не вложенных классов, которые описываются непосредственно в пространстве имен?
6. Какой спецификатор доступа подразумевается для этих классов по умолчанию?
7. С помощью какой операция создаётся экземпляр класса?
8. К каким типам данных относится класс?
9. Какие элементы классов присутствуют в единичном экземпляре в объекте класса?
10. Перечислите спецификаторы данных класса.
11. Какой спецификатор доступа элементов класса считается по умолчанию?
12. Имеют ли методы класса непосредственный доступ к его закрытым полям?
13. С помощью какой операции можно обратиться к полю класса?
14. Как обратиться к статическому полю класса и к константе?
15. Как обратиться к нестатическому элементу класса?
16. Для чего применяется параметр this в явном виде?
17. Для чего предназначен конструктор?
18. Перечислить свойства конструктора.
19. В каких случаях конструктор базового класса вызывается явным образом?
20. С помощью какого ключевого слова можно явным образом вызвать конструктор базового класса?
21. Для чего служит свойство класса?
22. Синтаксис объявления свойства.
23. Могут ли отсутствовать части get/set, или обе одновременно?
24. Когда свойство доступно только для чтения (read-only)?
25. Когда свойство доступно только для записи (write-only)?
26. Какие спецификаторы доступа можно задавать для частей свойства, объявленного со спецификатором public?
27. Какие спецификаторы доступа можно задавать для частей свойства, объявленного со спецификатором protected internal?