Абстракция против инкапсуляции в Java

Возможный дубликат:
Абстракция VS Скрытие информации VS инкапсуляция < / а>

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

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

Из вышеприведенного определения я понял, что создание переменных, пометка их как частные, создание геттера-установщика для этих переменных и использование объекта для доступа к этим геттерам и сеттерам. Таким образом, данные скрыты внутри объекта и доступны только через объект. Надеюсь, я прав.


Абстракция - это процесс в Java, который используется для скрытия определенных деталей и отображения только основных характеристик объекта. Другими словами, он имеет дело с внешним видом объекта (интерфейса).

Это то, что меня всегда смущает. Всякий раз, когда я думаю об абстракции, мне на ум приходит абстрактный класс (возможно, потому, что оба имеют ключевое слово Abstract). В приведенном выше определении говорится, что абстракция означает скрытие данных и отображение только необходимых деталей, но это то, что мы уже делаем в инкапсуляции, верно? тогда какая разница. Также я не понял, что является внешним видом объекта в он имеет дело с внешним видом объекта.

Может ли кто-нибудь пролить свет на это с помощью некоторых примеров из реальной жизни или, если возможно, некоторых программных примеров.


person Sandeep Kumar    schedule 15.08.2012    source источник


Ответы (3)


ОО-абстракция возникает во время проектирования на уровне класса с цель сокрытия сложности реализации в том, как функции, предлагаемые API / дизайном / системой, были реализованы, в некотором смысле упрощая "интерфейс" для доступа к базовой реализации. .

Процесс абстракции может повторяться на все более «более высоких» уровнях (слоях) классов, что позволяет строить большие системы без увеличения сложности кода и понимания на каждом уровне.

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

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

В определении Буча 1 объектно-ориентированная инкапсуляция достигается с помощью Скрытие информации, в частности, для сокрытия внутренних данных (полей / членов, представляющих состояние), принадлежащих экземпляру класса, путем обеспечения доступа к внутренним данным в контролируемым образом, и предотвращение прямого внешнего изменения этих полей, а также сокрытие любых внутренних методов реализации класса (например, путем их приватности).

Например, поля класса могут быть сделаны private по умолчанию, и только если требуется внешний доступ к ним, get() и / или set() (или Property) будут доступны из класса. (В современных ОО-языках поля могут быть помечены как readonly / final / immutable, что дополнительно ограничивает изменение, даже внутри класса).

Пример, когда НЕ применялось сокрытие информации (Плохая практика):

class Foo {
   // BAD - NOT Encapsulated - code external to the class can change this field directly
   // Class Foo has no control over the range of values which could be set.
   public int notEncapsulated;
}

Пример применения инкапсуляции полей:

class Bar {
   // Improvement - access restricted only to this class
   private int encapsulatedPercentageField;

   // The state of Bar (and its fields) can now be changed in a controlled manner
   public void setEncapsulatedField(int percentageValue) {
      if (percentageValue >= 0 && percentageValue <= 100) {
          encapsulatedPercentageField = percentageValue;
      }
      // else throw ... out of range
   }
}

Пример неизменяемой инициализации поля или только для конструктора:

class Baz {
   private final int immutableField;

   public void Baz(int onlyValue) {
      // ... As above, can also check that onlyValue is valid
      immutableField = onlyValue;
   }
   // Further change of `immutableField` outside of the constructor is NOT permitted, even within the same class 
}

Re: абстракция против абстрактного класса

Абстрактные классы - это классы, которые способствуют повторному использованию общности между классами, но сами по себе не могут быть созданы напрямую с помощью new() - абстрактные классы должны быть подклассами, и могут быть созданы только concrete (не абстрактные) подклассы. Возможно, одним из источников путаницы между Abstraction и abstract class было то, что на заре OO наследование более активно использовалось для повторного использования кода (например, со связанными абстрактными базовыми классами). В настоящее время композиция обычно предпочтительнее наследования, и для достижения абстракции доступно больше инструментов, например через интерфейсы, события / делегаты / функции, трейты / миксины и т. д.

Re: инкапсуляция против сокрытия информации

Значение инкапсуляции со временем изменилось, и в последнее время _ 17_ может также использоваться в более общем смысле при определении того, какие методы, поля, свойства, события и т. д. необходимо объединить в класс.

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

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

Например, в заявлении

Я инкапсулировал код доступа к данным в отдельный класс

.. интерпретация инкапсуляции примерно эквивалентна разделению проблем или Единого ответственного лица («S» в SOLID), и, возможно, может использоваться в качестве синоним рефакторинга.


[1] После того, как вы увидели изображение кота инкапсуляции, вы никогда не забудете инкапсуляцию - стр. 46 книги" Объектно-ориентированный анализ и дизайн с приложениями ", 2-е изд.

person StuartLC    schedule 15.08.2012
comment
Итак, Java API, который мы используем, является абстракцией? - person sras; 23.07.2015
comment
Да, на высоком уровне API действительно предоставляет более простую абстракцию для использования потребителем, блаженно не осознающим сложность, лежащую в основе его внутреннего дизайна. Очевидно, что Java - это язык со многими связанными высокоуровневыми средами. Тем не менее, я считаю, что более конкретно, примерно в то время, когда была придумана терминология принципалов OO-дизайна , эта абстракция более конкретно относилась к проектированию и декомпозиции на уровне классов, а не к структуре или дизайну на уровне предприятия. - person StuartLC; 23.07.2015

Проще говоря: вы делаете абстракцию, когда решаете, что реализовать. Вы делаете инкапсуляцию, когда скрываете что-то, что вы реализовали.

person mbm    schedule 15.08.2012

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

например У меня может быть Vehicle класс. Car будет происходить от Vehicle, как и Motorbike. Я могу спросить у каждого Vehicle количество колес, пассажиров и т. Д., И эта информация была извлечена и идентифицирована как общая для Cars и Motorbikes.

В моем коде я часто могу иметь дело с Vehicles с помощью общих методов go(), stop() и т. Д. Когда я добавляю новый тип транспортного средства позже (например, Scooter), большая часть моего кода не обращает внимания на этот факт, и реализация Scooter сама по себе беспокоит Scooter особенности.

person Brian Agnew    schedule 15.08.2012
comment
Не могли бы вы предоставить код, чтобы лучше объяснить ваш ответ? - person Rahul Gupta; 22.08.2018
comment
@RahulGupta, чтобы полностью понять это, вам нужно понять концепцию наследования. С помощью наследования вы создаете иерархию классов-родителей (родители высокого уровня абстрактны, а большинство дочерних элементов - Concerete) и передаете общие черты / свойства дочерним. Абстракция реализована, если все сделано правильно. - Родительские классы делают общие черты. (который скрыт с точки зрения пользователя, если пользователь сосредоточен на ребенке) - Дочерние классы, ориентированные на то, чтобы быть ребенком. (непрофессионалы: в детстве я не заботился о работе моих родителей, насколько это возможно, но меня волнует то, что я делаю.) - person cattarantadoughan; 09.08.2019