Разница между абстракцией и инкапсуляцией? - PullRequest
319 голосов
/ 13 апреля 2009

Какова точная разница между инкапсуляцией и абстракцией?

Ответы [ 39 ]

248 голосов
/ 13 апреля 2009

Большинство ответов здесь сосредоточены на ООП, но инкапсуляция начинается намного раньше:

  • Каждая функция представляет собой инкапсуляцию ; в псевдокоде:

    point x = { 1, 4 }
    point y = { 23, 42 }
    
    numeric d = distance(x, y)
    

    Здесь distance инкапсулирует вычисление (евклидова) расстояния между двумя точками на плоскости: оно скрывает детали реализации. Это инкапсуляция, чистая и простая.

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

    Суть qsort в том, что он не заботится о сортируемых данных - фактически, он не знает , какие данные он сортирует. Скорее, его тип ввода - это указатель без типа (void*), который является просто способом С сказать «мне нет дела до типа данных» (это также называется стиранием типа). Важным моментом является то, что реализация qsort всегда остается неизменной независимо от типа данных. Единственное, что может изменить - это функция сравнения, которая отличается от типа данных к типу данных. qsort поэтому ожидает, что пользователь предоставит упомянутую функцию сравнения в качестве аргумента функции.

Инкапсуляция и абстракция идут рука об руку настолько, что вы можете сказать, что они действительно неразделимы. Для практических целей это, вероятно, правда; Тем не менее, вот инкапсуляция, которая не так уж и абстрактна:

class point {
    numeric x
    numeric y
}

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

А вот пример абстракции, которая не является инкапсуляцией:

T pi<T> = 3.1415926535

Это универсальная переменная pi с заданным значением (π), и объявление не заботится о точном типе переменной. По общему признанию, мне было бы трудно найти что-то подобное в реальном коде: абстракция практически всегда использует инкапсуляцию. Однако вышеприведенное действительно действительно существует в C ++ (14) через шаблоны переменных (= общие шаблоны для переменных); с немного более сложным синтаксисом, например ::1055*

template <typename T> constexpr T pi = T{3.1415926535};
124 голосов
/ 13 апреля 2009

Инкапсуляция скрывает детали реализации, которые могут или не могут быть для общего или специализированного поведения (й).

Абстракция обеспечивает обобщение (скажем, над набором поведений).

Вот хорошее прочтение: Абстракция, инкапсуляция и сокрытие информации Эдварда В. Берара из Агентства объектов.

102 голосов
/ 24 марта 2015

Многие ответы и их примеры вводят в заблуждение.

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

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

Инкапсуляция: - Скрытие информации .
Абстракция: - Сокрытие реализации .

Пример:

class foo{
    private:
        int a, b;
    public:
        foo(int x=0, int y=0): a(x), b(y) {}

        int add(){    
            return a+b;   
        } 
}  

Внутреннее представление любого объекта класса foo скрыто за пределами класса. -> Инкапсуляция.
Любой доступный элемент (данные / функция) объекта foo ограничен и доступен только для этого объекта.

foo foo_obj(3, 4);
int sum = foo_obj.add();

Реализация метода add скрыта. -> Абстракция.

96 голосов
/ 13 апреля 2009

инкапсуляция помещает некоторые вещи в коробку и дает вам глазок; это удерживает вас от работы с шестеренками.

вычеркивание абстракции игнорирует детали, которые не имеют значения, например, есть ли у вещей шестерни, трещотки, маховики или ядерные сердечники; они просто "уходят"

примеры инкапсуляции:

  • трусы
  • 1010 * ящик для инструментов *
  • кошелек
  • сумка
  • капсула
  • замороженный карбонит
  • коробка с кнопкой или без нее
  • буррито (технически лепешка вокруг буррито)

примеры абстракций:

  • "группы вещей" - это абстракция (которую мы называем агрегацией)
  • "вещи, которые содержат другие вещи" - это абстракция (которую мы называем композицией)
  • «контейнер» - это другой вид абстракции «вещи, которые содержат другие вещи»; обратите внимание, что все примеры инкапсуляции являются видами контейнеров, но не все контейнеры демонстрируют / обеспечивают инкапсуляцию. Например, корзина - это контейнер, который не инкапсулирует свое содержимое.
63 голосов
/ 27 ноября 2012

Инкапсуляция означает скрытие данных, таких как использование геттера и сеттера и т. Д.

Абстракция означает скрытие реализации с использованием абстрактного класса и интерфейсов и т. Д.

40 голосов
/ 06 июля 2015

Абстракция - это обобщенный термин. т.е. инкапсуляция является подмножеством абстракции.

enter image description here

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

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

Предоставлено

30 голосов
/ 04 января 2014

Выше приведено много хороших ответов, но я собираюсь изложить свою точку зрения (Java) здесь.

Инкапсуляция данных просто означает перенос и контроль доступа логически сгруппированных данных в классе. Обычно оно связано с другим ключевым словом - Скрытие данных . Это достигается в Java с помощью модификаторов доступа .

Простым примером будет определение закрытой переменной и предоставление доступа к ней с помощью методов getter и setter или создание метода private, так как он используется только внутри класса. Пользователю не нужно знать об этих методах и переменных.

Примечание : Не следует неправильно понимать, что инкапсуляция связана только с сокрытием данных. Когда мы говорим об инкапсуляции, акцент должен делаться на группировку или упаковку или связывание связанных данных и поведения вместе.

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

Пример -

Допустим, у нас есть интерфейс Animal и функция makeSound () . Есть два конкретных класса Dog и Cat , которые реализуют этот интерфейс. Эти конкретные классы имеют отдельные реализации функции makeSound (). Теперь допустим, что у нас есть животное (мы получаем это из какого-то внешнего модуля). Все, что пользователь знает, это то, что объект, который он получает, является неким животным, и пользователь несет ответственность за печать звука животного. Один из способов перебора - проверить полученный объект на , идентифицировать его тип, затем typecast на этот тип Animal и затем call makeSound () для него. Но более аккуратный способ состоит в том, чтобы абстрагировать вещь . Используйте Animal как полиморфную ссылку и вызовите makeSound () для него. В время выполнения в зависимости от того, какой тип объекта является правильным, будет вызвана функция.

Подробнее здесь .

enter image description here

Сложная логика в печатной плате, которая заключена в сенсорную панель, а также удобный интерфейс (кнопки) для абстрагирования ее пользователю.

PS: Выше приведены ссылки на мой личный блог.

29 голосов
/ 13 апреля 2009
  • Абстракция позволяет вам сосредоточиться на том, что делает объект, а не на том, как он это делает
  • Инкапсуляция означает скрытие внутренних деталей или механизмов того, как объект что-то делает.

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

Позвольте мне привести пример на C #. Предположим, у вас есть целое число:

int Number = 5;
string aStrNumber = Number.ToString();

вы можете использовать метод, такой как Number.ToString (), который возвращает вам символьное представление числа 5 и сохраняет его в строковом объекте. Метод говорит вам, что он делает, а не как.

25 голосов
/ 26 декабря 2015

Это несколько нечеткие понятия, которые не являются уникальными для компьютерных наук и программирования. Я хотел бы высказать некоторые дополнительные мысли, которые могут помочь другим понять эти важные понятия.


Короткий ответ

Инкапсуляция - Скрытие и / или ограничение доступа к определенным частям системы, в то же время открывая необходимые интерфейсы.

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

Основное сходство заключается в том, что эти техники направлены на улучшение понимания и полезности.

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


Длинный ответ

Инкапсуляция

Вот пример инкапсуляции, которая, надеюсь, прояснит ситуацию:

Arduino Encapsulation

Здесь у нас есть Arduino Uno и Arduino Uno в корпусе. Вложение - отличное представление о том, что такое инкапсуляция.

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

Но помимо этого, инкапсуляция также направлена ​​на то, чтобы обеспечить эти внешние интерфейсы гораздо эффективнее. В нашем примере с Arduino это могут быть красивые кнопки и экран, которые значительно упрощают взаимодействие пользователя с устройством. Они предоставляют пользователю простые способы влиять на поведение устройства и получать полезную информацию о его работе, которая в противном случае была бы намного более сложной.

В программировании это включает в себя группирование различных компонентов в разделяемую конструкцию, такую ​​как function, class или object. Сюда также входит предоставление средств взаимодействия с этими конструкциями, а также методов получения полезной информации о них.

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

Абстракция

Хотя многие другие ответы здесь определяли абстракцию как обобщение, я лично считаю, что это определение ошибочно. Я бы сказал, что обобщение на самом деле является специфическим типом абстракции, а не наоборот. Другими словами, все обобщения являются абстракциями, но все абстракции являются , а не обязательно обобщениями.

Вот как мне нравится думать об абстракции:

Pixel Tree

Вы бы сказали, что на изображении есть дерево? Скорее всего, вы бы. Но действительно ли это 1073 * дерево? Ну конечно нет! Это группа пикселей, которые выглядят как нечто, что мы могли бы назвать деревом. Можно сказать, что это абстракция реального дерева. Обратите внимание, что некоторые визуальные детали дерева опущены. Кроме того, он не растет, не потребляет воду и не производит кислород. Как это могло? это просто набор цветов на экране, представленный байтами в памяти вашего компьютера.

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

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

Абстрактные классы

Абстракция в программировании также позволяет нам рассмотреть общие черты между несколькими "конкретными" типами объектов (типами, которые фактически существуют) и определить эти общие черты в пределах уникальной сущности. Например, наш класс Tree может наследоваться от abstract class Plant, который имеет несколько свойств и методов, применимых ко всем нашим классам, подобным растительным, но удаляет те, которые характерны для каждого типа завод. Это может значительно уменьшить дублирование кода и повысить удобство сопровождения.

Практическое различие abstract class и простого class заключается в том, что концептуально не существует "реальных" экземпляров abstract class. Не имеет смысла создавать объект Plant, потому что это недостаточно конкретно. Каждый «настоящий» Plant также является более конкретным типом Plant.

Кроме того, если мы хотим, чтобы наша программа была более реалистичной, мы могли бы рассмотреть тот факт, что наш класс Tree может быть слишком абстрактным сам по себе. В действительности каждый Tree является более конкретным типом Tree, поэтому мы могли бы создавать классы для таких типов, как Birch, Maple и т. Д., Которые наследуются от наших, возможно, теперь abstract, Tree класс.

1106 * JVM * Другим хорошим примером абстракции является Виртуальная машина Java (JVM) , которая предоставляет виртуальный или абстрактный компьютер для запуска кода Java. По сути, он забирает все специфические для платформы компоненты системы и обеспечивает абстрактный интерфейс «компьютера», не касаясь какой-либо конкретной системы. Разница

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

21 голосов
/ 13 апреля 2009

Инкапсуляция : Скрывает нежелательные / непредвиденные / правильные детали реализации от реальных пользователей объекта. например,

List<string> list = new List<string>();
list.Sort(); /* Here, which sorting algorithm is used and hows its 
implemented is not useful to the user who wants to perform sort, that's 
why its hidden from the user of list. */

Абстракция : Это способ обеспечения обобщения и, следовательно, общий способ работы с объектами огромного разнообразия. например, * +1008 *

class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
  // Aeroplane is a flying object
  // Aeroplane can be fueled
  // Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered 
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code 
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of 
// flying object they are.

// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();

// ** Fueling code does not need know what kind of vehicle it is, so far 
// as it can Fill Fuel**
...