
концепции ооп. часть 1
.pdf
Использование конструкторов
•Вызов конструктора без параметров (или конструктора по-умолчанию)
Circle c = new Circle();
• Вызов конструктора с параметрами
Circle c = new Circle(5);
Circle c = new Circle(1, 2, 5);

Поля и свойства
•Поле – переменная, хранит значение
•Свойство – пара методов (accessor, mutator), предназначенных для правильной инкапсуляции поля
–accessor (get) не должен выполнять длительных вычислений
–mutator (set) должен проверять значения, передавать уведомления
–Значение в set передается через служебное слово value

Свойства в .NET 1.0
• Объявление:
[Атрибуты] [спецификатор] тип Имя
{
get { тело } set { тело }
}
• Пример:
private double r; public double R
{
get { return r; } set { r = value; }
}

Анатомия свойств
• Не используем свойства:
private double r;
public double getR() { return r; } public void setR(double value)
{
if (value > 0) r = value;
}
• То же самое, с использованием свойств:
private double r; public double R
{
get { return r; } set
{
if (value > 0) r = value;
}
}

Анатомия свойств
• Вот так оно выглядит в дизассемблере:
internal class Circle
{
private double r; public double R
{
get
{
return this.r;
}
set
{
if (value > 0.0)
{
this.r = value;
}
}
}
}
.class private auto ansi beforefieldinit ConsoleApplica tion5.Circle extends [mscorlib]System.Object
{
// Fields
.field private float64 r // Methods
.method public hidebysig specialname instance float64 get_R () { … }
.method public hidebysig specialname instance void set_R (float64 'value') { … }
.property instance float64 R()
{
.get instance float64 ConsoleApplication5.Circle:: get_R()
.set instance void ConsoleApplication5.Circle::set _R(float64)
}
}

Анатомия свойств
• Использование свойств:
– Работаем через методы:
Circle c = new Circle();
//задание начального значения c.setR(5);
//увеличиваем радиус на 5 c.setR(c.getR() + 5);
//вывод на экран
Console.WriteLine(c.getR());
– Работаем через свойства:
Circle c = new Circle(); c.R = 5; // c.setR(5);
c.R += 5; // c.setR(c.getR() + 5); Console.WriteLine(c.R);

Свойства в .NET 2.0
• Объявление:
[Атрибуты] [спецификатор] тип Имя
{
[спецификатор] get { тело } [спецификатор] set { тело }
}
• Пример:
private double r; public double R
{
get { return r; }
private set { r = value; }
}

Свойства в .NET 3.0
• |
Пример: |
|
|
public double R { get; set; } |
|
• |
На самом деле: |
|
|
private double r; |
.field private float64 '<R>k__BackingField' |
|
public double R |
// Methods |
|
{ |
.method public hidebysig specialname |
|
get { return r; } |
instance float64 get_R () cil managed |
|
set { r = value; } |
{ |
|
} |
IL_0000: ldarg.0 |
|
|
IL_0001: ldfld float64 ConsoleApplication5 |
.Circle::'<R>k__BackingField'
}
…

Зависимые свойства
•Дан треугольник со сторонами a, b, c. Опишите класс,
позволяющий работать с заданным треугольником (считать его площадь).
•У сотрудника есть поля «дата рождения», «дата трудоустройства», «дата увольнения».
•Минимальное, текущее и максимальное значение.
S

Общие рекомендации по проектированию классов
•Все поля должны быть закрытыми.
•Доступ к полям осуществляется через свойства, которые проверяют валидность значений.
•В методах лучше взять за правило изменять значения свойств, а не полей.
•Не должно быть возможности привести объект в некорректное состояние.
•Начальной инициализацией объекта должен заниматься конструктор, или нужно генерировать исключения, если объект не инициализирован.
•Если поля объекта зависят друг от друга – их либо нельзя изменять независимо, либо надо генерировать исключение при неверном вводе.