В целях иллюстрации давайте инкапсулируем поле empName
Employee
необходимо добавить показанные ниже открытые методы. Обратите внимание, что метод SetName()
выполняет проверку входных данных, чтобы удостовериться, что строка имеет длину 15 символов или меньше. Если это не так, тогда на консоль выводится сообщение об ошибке и происходит возврат без внесения изменений в поле empName
.На заметку!
В случае класса производственного уровня проверку длины строки с именем сотрудника следовало бы предусмотреть также и внутри логики конструктора. Мы пока проигнорируем указанную деталь, но улучшим код позже, во время исследования синтаксиса свойств.class Employee
{
// Поля данных.
private string _empName;
...
// Метод доступа (метод get).
public string GetName() => _empName;
// Метод изменения (метод set).
public void SetName(string name)
{
// Перед присваиванием проверить входное значение.
if (name.Length > 15)
{
Console.WriteLine("Error! Name length exceeds 15 characters!");
// Ошибка! Длина имени превышает 15 символов!
}
else
{
_empName = name;
}
}
}
Такой подход требует наличия двух уникально именованных методов для управления единственным элементом данных. Чтобы протестировать новые методы, модифицируйте свой код следующим образом:
Console.WriteLine("***** Fun with Encapsulation *****\n");
Employee emp = new Employee("Marvin", 456, 30_000);
emp.GiveBonus(1000);
emp.DisplayStats();
// Использовать методы get/set для взаимодействия
// с именем сотрудника, представленного объектом.
emp.SetName("Marv");
Console.WriteLine("Employee is named: {0}", emp.GetName());
Console.ReadLine();
Благодаря коду в методе SetName()
Console.WriteLine("***** Fun with Encapsulation *****\n");
...
// Длиннее 15 символов! На консоль выводится сообщение об ошибке.
Employee emp2 = new Employee();
emp2.SetName("Xena the warrior princess");
Console.ReadLine();
Пока все идет хорошо. Мы инкапсулировали закрытое поле empName
GetName()
и SetName()
. Для дальнейшей инкапсуляции данных в классе Employee
понадобится добавить разнообразные дополнительные методы (такие как GetID()
, SetID()
, GetCurrentPay()
, SetCurrentPay()
). В каждом методе, изменяющем данные, может содержаться несколько строк кода, в которых реализована проверка дополнительных бизнес-правил. Несмотря на то что это определенно достижимо, для инкапсуляции данных класса в языке C# имеется удобная альтернативная система записи.Инкапсуляция с использованием свойств
Хотя инкапсулировать поля данных можно с применением традиционной пары методов get
set
, в языках .NET Core предпочтение отдается обеспечению инкапсуляции данных с использованием get
и set
соответственно. Следовательно, проектировщик класса по-прежнему может выполнить любую внутреннюю логику перед присваиванием значения (например, преобразовать в верхний регистр, избавиться от недопустимых символов, проверить вхождение внутрь границ и т.д.).Ниже приведен измененный код класса Employee
get
и set
.class Employee
{
// Поля данных.
private string _empName;
private int _empId;
private float _currPay;
// Свойства!
public string Name
{
get { return _empName; }
set
{
if (value.Length > 15)
{
Console.WriteLine("Error! Name length exceeds 15 characters!");