![](/user_photo/_userpic.png)
- •Глава 3. Классы. Объектно-ориентированное программирование
- •Классы и объекты
- •Инициализаторы объектов
- •Частичные классы
- •Модификаторы доступа
- •Internal: класс и члены класса с подобным модификатором доступны из любого места кода в той же сборке, однако он недоступен для других программ и сборок (как в случае с модификатором public).
- •Поля для чтения
- •Свойства и инкапсуляция
- •Инкапсуляция
- •Автоматические свойства
- •Инициализация автосвойств
- •Перегрузка методов и операторов
- •Перегрузка операторов
- •Статический конструктор
- •Доступ к членам базового класса из класса-наследника
- •Ключевое слово base
- •Полиморфизм и переопределение методов
- •Ключевое слово base
- •Запрет переопределения методов
- •Абстрактные классы
Инкапсуляция
Выше мы посмотрели, что через свойства устанавливается доступ к приватным переменным класса. Подобное сокрытие состояния класса от вмешательства извне представляет механизм инкапсуляции, который представляет одну из ключевых концепций объектно-ориентированного программирования. Применение модификаторов доступа типа private защищает переменную от внешнего доступа. Для управления доступом во многих языках программирования используются специальные методы, геттеры и сеттеры. В C# их роль, как правило, выполняют свойства.
Например, есть некоторый класс Account, в котором определено поле sum, представляющее сумму:
|
class Account { public int sum; } |
Поскольку переменная sum является публичной, то в любом месте программы мы можем получить к ней доступ и изменить ее, в том числе установить какое-либо недопустимое значение, например, отрицательное. Вряд ли подобное поведение является желательным. Поэтому применяется инкапсуляция для ограничения доступа к переменной sum и сокрытию ее внутри класса:
|
class Account { private int sum; public int Sum { get {return sum;} set { if (value > 0) { sum=value; } } } } |
Автоматические свойства
Свойства управляют доступом к полям класса. Однако что, если у нас с десяток и более полей, то определять каждое поле и писать для него однотипное свойство было бы утомительно. Поэтому с версии .NET 4.0 в фреймворк были добавлены автоматические свойства. Они имеют сокращенное объявление:
|
class Person { public string Name { get; set; } public int Age { get; set; }
public Person(string name, int age) { Name = name; Age = age; } } |
На самом деле тут также создаются поля для свойств, только их создает не программист в коде, а компилятор автоматически генерирует при компиляции.
С одной стороны, автоматические свойства довольно удобны. С другой стороны, стандартные свойства имеют ряд преимуществ: например, они могут инкапсулировать дополнительную логику проверки значения; нельзя создать автоматическое свойство только для записи или чтения, как в случае со стандартными свойствами.
Инициализация автосвойств
В C# 6.0 (Visual Studio 2015) была добавлена такая функциональность, как инициализация автосвойств:
|
class Person { public string Name { get; set; } = "Tom"; public int Age { get; set; } = 23; }
class Program { static void Main(string[] args) { Person person = new Person(); Console.WriteLine(person.Name); // Tom Console.WriteLine(person.Age); // 23
Console.Read(); } } |
И если мы не укажем для объекта Person значения свойств Name и Age, то будут действовать значения по умолчанию.
Еще одно изменение коснулось определения автосвойств. Например, если в C# 5.0 мы захотели сделать автосвойство доступным для установки только из класса, то надо было указать private set:
|
class Person { public string Name { get; private set; } public Person(string n) { Name = n; } } |
Кроме как из класса Person это свойство невозможно установить. В C# 6.0 нам необязательно писать private set:
|
class Person { public string Name { get;} public Person(string n) { Name = n; } } |