Свойства – это специализированные методы класса, предоставляющие открытый доступ к закрытым переменным класса. Приведем пример свойств, определенных в классе Person:
public double Height
{ get {return height; }
set
{ if (value >0)&&( value <230)&& (value >height)
height=value;
}
}
Использование такого свойства в клиентской части программы очень напоминает использование обычных переменных:
Console.WriteLine(p.Height); //используется get-блок для чтения значения
p.Height=178; //используется set-блок записи значения
p.Height++; //используется get- и set-блоки
Перечислим синтаксические особенности свойств:
1. Свойства обычно являются открытыми.
2. Свойства не имеют списка параметров (даже пустого).
3. Тело свойства может состоять из двух блоков операторов – первый начинается со слова get, а второй – со слова set. Каждый из этих блоков не является обязательным, но хотя бы один из них должен быть определен.
Когда в клиентской части происходит обращение к свойству по чтению, управление передается в get-блок, который должен вернуть интересующее нас значение закрытой переменной.
Когда в клиентской части происходит обращение к свойству по записи, управление передается в set-блок, который должен обеспечить корректное присваивание закрытой переменной нового значения. Это новое значение представлено в теле set-блока ключевым словом value, которое играет роль формального параметра, принимающего фактическое значение, указываемое в клиентском коде.
Если в свойстве не определен set-блок, то реализуется доступ только по чтению. Если в свойстве не определен get-блок, то реализуется доступ только по записи (полезно для паролей). Можно реализовать и более экзотические варианты, например, чтение и однократная запись.
Свойства можно использовать для представления такой информации об объектах класса, которая не представлена непосредственно в виде переменных класса, но может быть вычислена на их основании.
Например, если в классе Triangle (треугольник) имеются переменные, соответствующие длинам трех сторон, то можно определить полезное свойство Perimeter (периметр). Однако такое свойство будет реализовывать доступ только по чтению:
class Triangle
{ private double a,b,c;
public double Perimeter { get { return (a+b+c); } }
Этот пример служит демонстрацией важного преимущества инкапсуляции. Даже если внутреннее представление данных класса изменится, программный код, использующий этот класс, изменять не придется. Допустим, в представлении треугольника вместо трех длин сторон решено использовать две длины сторон и угол между ними. Тогда в классе Triangle нужно соответствующим образом изменить реализацию свойства Perimeter.
Написание программ – процесс очень сложный. И поэтому важно иметь средства, облегчающие общение между программистами, а также другими участниками программного проекта. Язык программирования для этой цели не подходит – текст программы быстро становится громоздким, и проследить взаимосвязи в нем становится очень трудно. В этом случае обычно используются более наглядные визуальные конструкции.
На данный момент сообщество программистов выработало достаточно универсальный и, что еще важнее, стандартный язык таких обозначений – Unified Modelling Language (UML – унифицированный язык моделирования). В состав этого языка входит довольно большое количество разновидностей обозначений – так называемых диаграмм. В данном кратком пособии будем использовать только одну разновидность диаграмм – статические диаграммы классов (в дальнейшем – диаграммы классов).
На диаграмме классов каждый класс изображается прямоугольником, разделенным на три части. В первой указывается только имя класса, во второй перечисляются переменные класса, в третьей – методы класса. Иногда имеет смысл использовать сокращенное обозначение класса – прямоугольник, состоящий только из имени класса.
Полное обозначение класса
Сокращенное обозначение
Перед открытыми переменными и методами класса указывается знак + (вместо public), а перед закрытыми – знак – (вместо private). Кроме того, при описании переменных, методов и параметров методов сначала указывается имя, а затем после символа «:» тип. На диаграмме класса реализация метода не указывается. Таким образом, детализированная диаграмма класса Person будет выглядеть следующим образом:
Обратите внимание на описание свойства Height – справа от его имени указывается пара фигурных скобок с ключевыми словами get и/или set.