Урок №115. Инкапсуляция, Геттеры и Сеттеры
На предыдущем уроке мы узнали, что переменные-члены класса по умолчанию являются закрытыми. Новички, которые изучают объектно-ориентированное программирование, очень часто не понимают, почему всё обстоит именно так.
Зачем делать переменные-члены класса закрытыми?
В качестве ответа, воспользуемся аналогией. В современной жизни мы имеем доступ ко многим электронным устройствам. К телевизору есть пульт дистанционного управления, с помощью которого можно включать/выключать телевизор. Управление автомобилем позволяет в разы быстрее передвигаться между двумя точками. С помощью фотоаппарата можно делать снимки.
Все эти 3 вещи используют общий шаблон: они предоставляют вам простой интерфейс (кнопка, руль и т.д.) для выполнения определенного действия. Однако, то, как эти устройства фактически работают, скрыто от вас (как от пользователей). Для нажатия кнопки на пульте дистанционного управления вам не нужно знать, что выполняется «под капотом» пульта для взаимодействия с телевизором. Когда вы нажимаете на педаль газа в своем автомобиле, вам не нужно знать о том, как двигатель внутреннего сгорания приводит в движение колеса. Когда вы делаете снимок, вам не нужно знать, как датчики собирают свет в пиксельное изображение.
Такое разделение интерфейса и реализации чрезвычайно полезно, поскольку оно позволяет использовать объекты, без необходимости понимания их реализации. Это значительно снижает сложность использования этих устройств и значительно увеличивает их количество (устройства с которыми можно взаимодействовать).
По аналогичным причинам разделение реализации и интерфейса полезно и в программировании.
Инкапсуляция
В объектно-ориентированном программировании инкапсуляция (или «сокрытие информации») — это процесс скрытого хранения деталей реализации объекта. Пользователи обращаются к объекту через открытый интерфейс.
В языке C++ инкапсуляция реализована через спецификаторы доступа. Как правило, все переменные-члены класса являются закрытыми (скрывая детали реализации), а большинство методов являются открытыми (с открытым интерфейсом для пользователя). Хотя требование к пользователям использовать публичный интерфейс может показаться более обременительным, нежели просто открыть доступ к переменным-членам, но на самом деле это предоставляет большое количество полезных преимуществ, которые улучшают возможность повторного использования кода и его поддержку.
Преимущество №1: Инкапсулированные классы проще в использовании и уменьшают сложность ваших программ.
С полностью инкапсулированным классом вам нужно знать только то, какие методы являются доступными для использования, какие аргументы они принимают и какие значения возвращают. Не нужно знать, как класс реализован изнутри. Например, класс, содержащий список имен, может быть реализован с использованием динамического массива, строк C-style, std::array, std::vector, std::map, std::list или любой другой структуры данных. Для использования этого класса, вам не нужно знать детали его реализации. Это значительно снижает сложность ваших программ, а также уменьшает количество возможных ошибок. Это является ключевым преимуществом инкапсуляции.
Все классы Стандартной библиотеки C++ инкапсулированы. Представьте, насколько сложнее был бы процесс изучения языка C++, если бы вам нужно было знать реализацию std::string, std::vector или std::cout (и других объектов) для того, чтобы их использовать!
Преимущество №2: Инкапсулированные классы помогают защитить ваши данные и предотвращают их неправильное использование.
Глобальные переменные опасны, так как нет строгого контроля над тем, кто имеет к ним доступ и как их используют. Классы с открытыми членами имеют ту же проблему, только в меньших масштабах. Например, допустим, что нам нужно написать строковый класс. Мы могли бы начать со следующего:
What is the < get; set; >syntax in C#?
I am learning ASP.NET MVC and I can read English documents, but I don’t really understand what is happening in this code:
What does this mean: < get; set; >?
![]()
20 Answers 20
It’s a so-called auto property, and is essentially a shorthand for the following (similar code will be generated by the compiler):
So as I understand it < get; set; >is an «auto property» which just like @Klaus and @Brandon said is shorthand for writing a property with a «backing field.» So in this case:
However if you’re like me — about an hour or so ago — you don’t really understand what properties and accessors are, and you don’t have the best understanding of some basic terminologies either. MSDN is a great tool for learning stuff like this but it’s not always easy to understand for beginners. So I’m gonna try to explain this more in-depth here.
get and set are accessors, meaning they’re able to access data and info in private fields (usually from a backing field) and usually do so from public properties (as you can see in the above example).
There’s no denying that the above statement is pretty confusing, so let’s go into some examples. Let’s say this code is referring to genres of music. So within the class Genre, we’re going to want different genres of music. Let’s say we want to have 3 genres: Hip Hop, Rock, and Country. To do this we would use the name of the Class to create new instances of that class.
Now that we’ve created the instances of the Genre class we can set the genre names using the ‘Name’ property that was set way up above.
We can set the name of ‘g1’ to Hip Hop by writing the following
What’s happening here is sort of complex. Like I said before, get and set access information from private fields that you otherwise wouldn’t be able to access. get can only read information from that private field and return it. set can only write information in that private field. But by having a property with both get and set we’re able do both of those functions. And by writing g1.Name = «Hip Hop»; we are specifically using the set function from our Name property
set uses an implicit variable called value . Basically what this means is any time you see «value» within set , it’s referring to a variable; the «value» variable. When we write g1.Name = we’re using the = to pass in the value variable which in this case is «Hip Hop» . So you can essentially think of it like this:
It’s Important to note that the above example isn’t actually written in the code. It’s more of a hypothetical code that represents what’s going on in the background.
So now that we’ve set the Name of the g1 instance of Genre, I believe we can get the name by writing
and if we ran this we would get «Hip Hop» in our console.
So for the purpose of this explanation I’ll complete the example with outputs as well
Property C# | Свойства C# и аксессоры get и set
В прошлой теме были рассмотрены объекты на C#. Напомню, что каждому объекту реального мира в соответствие ставится класс, описывающий его структуру и набор операций, которые могут выполняться самим объектом, либо же проводиться над ним. Но объект может не только выполнять какие-то действия, но и имеет определенные параметры — свойства C#.
Свойства C#
Свойства C# представляют собой отдельную структуру данных. В теме «Объекты на C#» был приведен пример кода:
Для класса «Персонаж» был объявлен набор переменных. На самом деле, подобный код считается примером очень плохого стиля программирования, потому как согласно правилам хорошего кода переменные обязаны быть закрытыми для изменения извне. Открытыми могут быть только свойства.
Аксессоры get и set
Итак, чтобы превратить открытые переменные в свойства, достаточно добавить < get; set; >после каждой из переменных. get и set — это аксессоры, при помощи которых может быть прописана логика установки и чтения значений закрытых свойств. Приведем написанный выше код к корректному виду.
Аксессор get отвечает за получение значения некоторой закрытой переменной или свойства, set, напротив, обрабатывает логику установки значения переменной, либо свойства. В примере, представленном выше, вы можете заметить ключевое слово value. Оно обозначает значение, которое пришло свойству извне и должно быть обработано. Кроме полной формы аксессоры могут использоваться в сокращенном виде: < get; set; >, — таким образом мы говорим, что свойство может быть и установлено, и прочитано извне. При необходимости аксессорам могут быть указаны модификаторы доступа, чтобы ограничить их доступность.
Персонаж с полосой hp
В общем-то это все, что необходимо знать о свойствах в C#. Удачных вам экспериментов, коллеги.
Кроме того, рекомендую прочитать статью Соединение строк SQL. А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.