Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник_С#_ч_2.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
3 Мб
Скачать
☆

8.2 Деструкторы

В языке С# классы могут содержать специальные методы деструкторы. В функциональном плане они должны осуществлять действия, обратные тем, что реализуют конструкторы. Однако особенностью деструкторов языка С# является то, что они не занимаются освобождением памяти, выделяемой конструктором соответствующим объектом (за этим следит сборщик мусора), а освобождают ресурсы, выделенные объекту, например, закрывают связанные с ним файлы, связь с сервером базы данных, связь с другим компьютером и т.д.

Также как у конструктора имя деструктора совпадает с именем класса, но перед именем деструктора устанавливается символ «~» – тильда. Например, если бы наш класс treyg содержал деструктор, то его запись выглядела бы следующим образом:

public ~treyg()

{ тело_деструктора }

Деструктор нельзя вызвать непосредственно в программе — он автоматически вызывается сборщиком мусора при удалении объекта из кучи. Освобождение ресурсов, выделяемых объекту, на практике осуществляется автоматически после того, как надобность в них отпадает, поэтому деструкторы конструктивно присутствуют в структуре класса, но, как правило, не создаются – либо используются по умолчанию.

8.3 Свойства

Один из принципов объектно-ориентированного программирования является инкапсуляция. Формально инкапсуляция это объединение полей и методов класса с целью защиты данных от непосредственного доступа из программы. Поля объекта используются через его интерфейс – совокупность правил доступа или свойства. Скрытие полей объекта – их инкапсуляция (от слова «капсула») осуществляется через свойства.

Свойства представляют собой специальные методы, которые на самом деле состоят из двух методов – get() и set() и некоторого поля объекта. Метод get() возвращает текущее значение соответствующего поля объекта, а метод set() помещает в поле объекта новое значение. Эти методы вызываются автоматически всякий раз, когда программа хочет получить значение «свойства» или изменить его. С точки зрения синтаксиса свойства ничем не отличаются от полей: они могут стоять в левой части оператора присваивания либо являться членом выражения в его правой части. Например, закрытому полю int a можно записать следующее свойство целого типа Aa.

public class treyg

{

private int a, b, c, p;

public int Aa

{

get { return a;}

set { a = value;}

}

public string ss;

. . .

В программе, после создания объекта t полю a можно присвоить новое значение через свойство Aa следующим образом:

int A, B, C;

treyg t = new treyg();

A = Convert.ToInt32(textBox1.Text);

B = Convert.ToInt32(textBox2.Text);

C = Convert.ToInt32(textBox3.Text);

t.Aa = A; ,

или переменной программы А присвоить значение поля а объекта t следующим образом:

A = t.Aa; ,

где t.Aa – это свойство класса treyg.

В приведенном примере свойством t.Аа мы фактически закрытое поле а класса treyg превратили в открытое поле – это можно сделать проще объявив в классе вместо спецификатора private спецификатор public.

Естественно свойства предназначены для реализации более сложной логики доступа к закрытому полю класса. В нашем примере в свойство установки нового значения полю класса мы можем включить проверку значения на условие > 0 и на реализацию только одной попытки записи, например:

set { if (a == 0 && value > 0) a = value;}

Любой из методов доступа свойства (но не оба сразу) может отсутствовать. В этом случае мы получаем свойства, предназначенные только для чтения или только для записи.