Инкапсуляция и свойства. формат записи свойств и правила их использования
Все классы должны соответствовать трём принципам ООП:
1) Инкапсуляция. Как данный класс скрывает внутренние особенности реализации объектов.
2) Наследование. Как язык программирования обеспечивает возможность многократно использовать программный код какого-то класса.
3) Полиморфизм. Как язык программирования позволяет интерпретировать родственные объекты унифицированным образом. Например, перегрузка методов, конструкторов, операторов позволяет разрабатывать члены класса с одинаковыми именами, а перегрузка операторов позволяет выполнять операции над объектами, как будто это числа.
Одним из аспектов инкапсуляции является защита данных. В идеале данные объекта (поля) определяются как приватные (закрытые). Это значит, что они будут доступны только внутри класса. Если пользователь класса желает изменить состояние объекта, то он должен это делать косвенно, с помощью открытых (public) методов чтения (get) и модификации (set).
В отличие от этих традиционных методов в языке C# реализован принцип инкапсуляции на основе использования свойств. Свойства появились ещё в Visual Basic.
Свойства - это специальный тип класса, позволяющий получить доступ к данным об объекте. Примеры свойств в OС Windows:
1) Размеры окна
2) Цвет фона окна
3) Описание шрифта: начертание, размер, …
4) …
Обычные поля класса (например, координаты точки double x, y) требуют выделения памяти, а для хранения свойств память не выделяется. Свойства используются для инкапсуляции полей в классе, позволяя выполнять чтение и запись их значений.
Свойства в C# состоят из имени, одного или двух блоков программного кода, называемых функциями доступа (для чтения - get, для записи – set). Эти функции называют аксессорами (access– доступ), средствами доступа (get иset).
Основное достоинство свойств состоит в том, что их имена можно использовать в выражениях, в инструкциях присваивания, подобно обычной переменной, хотя в действительности здесь автоматически будут вызываться get и set-аксессоры.
Свойства можно использовать при дальнейшей разработке класса, то есть внутри методов, конструкторов и так далее.
Формат записи свойств
public Тип_свойства (тип поля класса) Имя_свойства
{
Get
{
//Программный код аксессора чтения поля.
}
Set
{
//Программный код аксессора записи.
}
}
Аксессор set автоматически принимает параметр с именем value(значение), который содержит значение, присваиваемое полю.
Разработка свойств для полей класса Point и решение задач с их использованием
Задание: для класса Point разработать свойства: Koord_X и Koord_Y:
public double Koord_X
{
get { return x; }
set { x = value; }
}
public double Koord_Y
{
get { return y; }
set { y = value; }
}
Протестируем в Main():
T7.Koord_X=-999;
T7.Koord_Y=888;
T7.Show();
//Выполнить!
//Здесь отработали set-аксессоры,
if (T5.Koord_X>T5.Koord.Y) //а здесь get-аксессоры!
Console.WriteLine(“x>y”);
Else
Console.WriteLine(“x <=y”);
//Выполнить!
Примечания:
1) Можно создавать свойства, предназначенные только для чтения (определив лишь get-аксессор), либо только для записи (определив лишь set-аксессор).
2) Свойство не должно изменить состояние объекта при вызове get-аксессора, хотя несоблюдение этого правила компилятор не обнаружит. Это значит, что get-операция должна быть минимально простой (в большинстве случаев это оператор return…).
3) Так как в свойстве не определяется область памяти, его нельзя передавать методу в качестве refили out-параметров.
4) Свойства нельзя перегружать. Лучше разработать для одного и того же поля два различных свойства.
В C# используются и статические свойства (в заголовке присутствует слово static). Тогда для их вызова не нужен экземпляр класса, а вызываются они по имени класса: Имя_класса.Имя_свойства, но статические свойства должны оперировать со статическими полями.
Задача-пример: Дан массив точек на плоскости. Имеется ли в нём хотя бы одна точка, расположенная в четвёртом координатном углу на биссектрисе.
Создание массива точек смотри: Тема 4, §1. Перегрузка методов и конструкторов как механизм реализации полиморфизма.
Объявим номер искомой точки:
int nom = -1; // -1 означает, что нужной точки нет
В ответе нужно проанализировать переменную nom. Если она равна -1, то выдать соответствующее сообщение («Такой точки нет»). В противном случае вывести номер точки и её координаты:
for (i=0; i<mas.Length; i++)
if (mas[i].Koord_X=-mas[i].Koord_Y && mas[i].Koord_X>0)
{
nom=i;
break;
}
if (nom == -1)
Console.WriteLine("Точки, лежащей на биссектрисе в 4ом углу - НЕТ!");
Else
{
Console.WriteLine("Такая точка есть, её номер "+nom+" ее координаты: ");
mas[nom].Show());
}
//Выполнить!
Итак, свойства используются с той же целью, что и классическая пара методов get() и set(…) (чтение и модификация данных) для реализации инкапсуляции. Преимущество свойств заключается в том, что пользователи объекта получают возможность изменять его внутренние данные, а так же свойства удобно использовать в выражениях (арифметических и логических). Более того, свойства можно применять в новых методах класса.