Что такое инкапсуляция?

У меня есть два определения инкапсуляции, которые не могут вписаться в одно определение.

  • Инкапсуляция - это скрытие данных. Используя частные, защищенные и общедоступные, упаковывайте данные в один компонент.
  • Независимо от того, какие изменения инкапсулируют его. Защита всего, что подвержено изменениям.

Как эти два определения говорят об одном и том же понятии?

Ответ 1

Инкапсуляция, вероятно, является самой непонятой концепцией ООП.

Инкапсуляция - это не скрытие данных!

"Инкапсуляция" происходит от "капсулы". Это означает объединение вещей, закрытие их в пакете, а "вещи", о которых мы говорим, - это данные и функции. Программирование без инкапсуляции означает, что функции, относящиеся к данным, "плавают вокруг", где-то в вашем коде, и хотя они обрабатывают ваши данные и даже принимают этот конкретный тип в качестве входных данных, они отделены от ваших данных.

Позвольте мне привести пример, не сосредотачиваясь на "public" и т.п.: если у вас есть класс, который имеет дело со сложными числами, которые имеют реальную и мнимую часть, вы можете просто определить его следующим образом:

class complex {
    double real;
    double imaginary;
};

При использовании старого стиля pre-encapsulation, который использовался, например, на C, чтобы получить абсолютное значение этого числа, вы бы определили такую ​​функцию:

double absolute(double real, double imaginary);

И это не будет связано с классом вообще! Конечно, вы также можете определить функцию, которая принимает комплексный класс в качестве входных данных, но все равно будет внешней функцией. Таким образом, чтобы использовать его, вам нужно будет сделать это:

complex A;
A.real = 1;
A.imaginary = -3;

и чтобы получить абсолютное значение, вы должны были бы вызвать

absolute(A.real, A.imaginary);

Вместо этого вы можете использовать инкапсуляцию и поместить данные и функции вместе:

class complex {
    double real;
    double imaginary;
    double absolute();  // inside the class, encapsulated into it!
};

а затем, чтобы получить абсолютное значение, вам просто нужно вызвать метод, например

A.absolute();

Это вовсе не требует скрытия данных. Преимущество состоит в том, что код более управляемый, потому что вы можете четко видеть все связанные вещи (то есть данные и функции), сгруппированные вместе, поэтому с первого взгляда вы знаете, что у вас есть (данные) и что вы можете делать с это (методы).

Скрывать информацию было бы невозможно без этого, потому что это означает, что вы ограничиваете доступ к некоторым членам (частным) извне, поэтому вы должны иметь некоторые методы внутри, или вы не сможете ничего сделать с помощью ваши данные!

В то же время скрытие информации помогает эффективно использовать инкапсуляцию: если люди могут получать доступ к данным извне, существует очень большая опасность для других кодеров, которые пишут собственный (не инкапсулированный) код, чтобы иметь дело с вашим данные, которые, по крайней мере, приведут к дублированию кода (т.е. к бесполезным усилиям) и к несоответствиям, если реализации несовместимы. Вместо этого скрытие данных означает, что для доступа к конфиденциальным данным все ДОЛЖНЫ использовать общедоступные методы, которые предоставляются, так что они одинаковы для всех.

Поэтому для скрытия данных требуется инкапсуляция, и в то же время ей помогает скрытие данных. Вместе они работают хорошо, но это не одно и то же!

Вернемся к вашему вопросу: в свете этого определение 1 неверно. И 2, как отмечено CommuSoft, на самом деле не является определением, это правило. И я добавлю, что это правило большого пальца о том, когда использовать скрытие данных, а не инкапсуляцию.

На стороне примечания, electrometro предполагает, что это может быть дубликат этого вопроса. Я думаю, что стоит отметить, что большинство ответов там неверны, включая верхний ответ, который представляет собой пример инкапсуляции, которая фактически является противоположной инкапсуляции.

Если вам нужны внешние ссылки, вот две статьи об этом:

Инкапсуляция не скрывает информацию

Абстракция, инкапсуляция и скрытие информации (обратите внимание, что когда он начинает абзац под названием "ENCAPSULATION" и цитирует множество определений, он просто пытается показать путаницу вокруг этой темы, эти определения неверны, как он объясняет позже!)

Ответ 2

Скрытие данных - это контроль. Когда вы скрываете данные, вы скрываете их от других программистов (включая ваше будущее), потому что они могут делать что-то неправильное с данными, потому что они не знают об этом так же хорошо, как и вы. Поэтому вы хотите тщательно контролировать, как они используют данные - в этом случае, скрывая это, ограничивая доступ и видимость.

Инкапсуляция не является практикой "защиты всего, что подвержено изменениям". Статьи, которые утверждают, что это, являются чрезмерно обобщающими, поскольку большинство методов разработки программного обеспечения относятся к "защите" вещей, которые мы можем изменить позже. Что вы должны знать, так это то, что часто бывает полезно исследовать вещи, которые подвержены изменениям, и решить, какие ограничения вы хотите использовать, как другие люди видят и используют эти вещи - как вы можете инкапсулировать эти вещи.


... Точно так же инкапсуляция также не является практикой "сдачи функций вместе с данными", как несколько статей, связанных в другом ответе. Правильным термином для этого может быть модуляция или простое старое объектно-ориентированное программирование - существует много связанных понятий. Эти методы могут привести к инкапсуляции, но называть их инкапсуляцией является запутанным, особенно для новичков. Инкапсуляция действительно касается "скрытия" данных. (Чтобы взять несколько продвинутый пример, в JavaScript вы можете поместить значение вместе с функцией либо как свойство объекта функции, либо через закрытие. Ни одно из них не использует поля, они не включают использование методов класса /object/prototype, оба помещают данные и функцию "вместе", но только закрытие будет инкапсулировать данные, навязывая ограничения доступа.)

Ответ 3

Инкапсуляция - это скрытие данных. Причина состоит в том, чтобы группировать аналогичные функции, которые могут измениться в будущем гораздо более управляемым образом.

Инкапсуляция может быть достигнута гораздо больше, чем просто использование модификаторов видимости.

Ответ 4

Я бы пошел со вторым как определение инкапсуляции. Я вижу это так же. Инкапсуляция - это механизм защиты остальной части вашего кода от изменений.

Первое утверждение более ограничительное. При инкапсуляции вы не скрываете только данные, а также реализацию. И модификаторы видимости - это просто средства для получения инкапсуляции. Вы используете public для методов, которые доступны из других классов. Их изменение влияет на внешний код, который их вызывает. В то время как частные скрывают то, что вы не хотите видеть снаружи, и которые могут свободно перемещаться без каких-либо воздействий на другие классы.

Таким образом, второй оператор является определением инкапсуляции, а первый - подсказкой о том, как его получить.

Ответ 5

Цитата из Википедии:

"Инкапсуляция - это упаковка данных и функций в один компонент. Особенности инкапсуляции поддерживаются с использованием классов на большинстве объектно-ориентированных языков программирования, хотя существуют и другие альтернативы.

В языках программирования инкапсуляция используется для обозначения одного из двух связанных, но разных понятий, а иногда и их комбинации:

  • Языковой механизм ограничения доступа к некоторым компонентам объекта.

  • Конструкция языка, которая облегчает объединение данных с помощью методов (или других функций), работающих с этими данными.