Чим відрізняються абстракція та інкапсуляція?


74

Я готуюсь до співбесіди і вирішив розглянути свої концепції ООП. Доступні сотні статей, але, схоже, кожна з них описує їх по-різному. Хтось каже

Абстракція - це "процес ідентифікації загальних зразків, що мають систематичні варіації; абстракція представляє загальний зразок і забезпечує засіб для уточнення, який варіант використовувати" (Річард Габріель).

і досягається завдяки абстрактним заняттям.

Деякі інші кажуть

Абстракція означає показати клієнту об’єкта лише необхідні деталі

і

Скажімо, у вас є метод "CalculateSalary" у своєму класі Employee, який приймає EmployeeId як параметр і повертає зарплату працівника за поточний місяць як ціле число. Тепер, якщо хтось хоче застосувати цей метод. Йому не потрібно дбати про те, як об'єкт працівника обчислює зарплату? Єдине, що його повинно турбувати, це назва методу, його вхідні параметри та формат результуючого члена,

Я гуглив знову і знову, і, здається, жоден з результатів не дає мені правильної відповіді. Тепер, де інкапсуляція укладається у все це? Я шукав і знайшов запитання про переповнення стека . Тут сказано навіть, що відповіді на ці запитання бентежили

Інкапсуляція - це стратегія, яка використовується як частина абстракції. Інкапсуляція відноситься до стану об’єктів - об’єкти інкапсулюють свій стан і приховують його зовні; зовнішні користувачі класу взаємодіють з ним за допомогою його методів, але не можуть отримати безпосередній доступ до стану класів. Тож клас абстрагує деталі реалізації, пов’язані з його станом.

І тут інший відомий член каже:

Це різні поняття.

Абстракція - це процес доопрацювання всіх непотрібних / неважливих атрибутів об’єкта та збереження лише тих характеристик, які найкраще підходять для вашого домену.

Зараз я переплутав із цілою концепцією. Я знаю про абстрактний клас, успадкування, специфікатори доступу та все. Я просто хочу знати, як я повинен відповісти, коли мене запитують про абстракцію та / або інкапсуляцію в інтерв’ю.

Будь ласка, не позначайте це як дублікат . Я знаю, що є кілька подібних питань. Але я хочу уникнути плутанини між суперечливими поясненнями. Хтось може запропонувати надійне посилання? Посилання на запитання щодо stackoverflow також вітається, якщо воно знову не створює плутанини. :)

EDIT: Мені потрібні відповіді, трохи орієнтовані на c #


4
Всі ці відповіді мене знову бентежать :(
Aparan

3
Я почну щедроту з цього питання.
Aparan

2
Проблема полягає в тому, що для цих понять не існує точних визначень, а самі слова мають багатозначне значення навіть у контексті об’єктної орієнтації. Якщо ви говорите про це в інтерв'ю, я сподіваюся, цього буде достатньо!
Метью Уотсон,

2
@MatthewWatson: If you talk about that in an interview, I would hope that would be sufficient! Я вас не зрозумів.
Aparan

1
Сподіваюся, ця стаття дасть дещо чітке уявлення про різницю цих двох ... :)
Цікавість

Відповіді:


50

Абстракція означає показати клієнту об’єкта лише необхідні деталі

Насправді це інкапсуляція. також перегляньте першу частину статті вікіпедії, щоб вас не бентежили інкапсуляція та приховування даних. http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)

майте на увазі, що просто приховування всіх членів класу 1: 1 за властивостями - це зовсім не інкапсуляція. інкапсуляція полягає у захисті інваріантів та приховуванні деталей реалізації.

ось хороша стаття про це. http://blog.ploeh.dk/2012/11/27/Encapsulationofproperties/ також погляньте на статті, на які посилається ця стаття.

класи, властивості та модифікатори доступу - це інструменти для забезпечення інкапсуляції в c #.

ви робите інкапсуляцію, щоб зменшити складність.

Абстракція - це "процес ідентифікації загальних зразків, що мають систематичні варіації; абстракція представляє загальний зразок і забезпечує засіб для уточнення, який варіант використовувати" (Річард Габріель).

Так, це хороше визначення для абстракції.

Це різні поняття. Абстракція - це процес доопрацювання всіх непотрібних / неважливих атрибутів об’єкта та збереження лише тих характеристик, які найкраще підходять для вашого домену.

Так, це різні поняття. майте на увазі, що абстракція насправді протилежна тому, щоб зробити об’єкт придатним ТІЛЬКИ ДЛЯ ВАШОГО домену. це для того, щоб зробити об’єкт придатним для домену загалом!

якщо у вас є реальна проблема та ви надаєте конкретне рішення, ви можете використовувати абстракцію, щоб оформити більш загальне рішення, яке також може вирішити більше проблем, що мають однакову загальну схему. таким чином ви можете збільшити повторне використання для своїх компонентів або використовувати компоненти, створені іншими програмістами, створеними для того самого домену або навіть для різних доменів.

хорошими прикладами є класи, надані фреймворком .net, наприклад список або колекція. це дуже абстрактні класи, якими ви можете користуватися майже скрізь та у багатьох доменах. Уявіть, якби .net реалізував лише клас EmployeeList та CompanyList, які могли містити лише список співробітників та компаній із певними властивостями. такі заняття були б марними у багатьох випадках. і яка б це була біль, якби вам довелося повторно впровадити всю функціональність для CarList, наприклад. Отже, "Список" АВТОРИСТОВАНИЙ від співробітників, компаній та автомобілів. Список сам по собі є абстрактним поняттям, яке може реалізувати його власний клас.

Інтерфейси, абстрактні класи або успадкування та поліморфізм - це інструменти для забезпечення абстракції в c #.

ви робите абстракцію, щоб забезпечити можливість повторного використання.


2
stackoverflow.com/a/8960961/2401223 Там сказаноEncapsulation is a strategy used as part of abstraction
Aparan

Я розумію .. за абстракцією є різні значення. Вікіпедія також відрізняється між "Абстракція" та "Принцип абстракції". Дотримуйтесь того, що сказав вам Метью Уотсон у коментарях: "Проблема полягає в тому, що для цих понять немає точних визначень, а самі слова мають багатозначне значення навіть у контексті об'єктної орієнтації". Поки ви можете надати їм на один руд більше значень в інтерв'ю, все буде добре :)
Егі,

Дякую. Я збираюся слідувати цій пораді :)
Апаран,

"Список сам по собі є абстрактним поняттям" - я думаю, що він відхиляється від концепції програмування абстракції, оскільки клас List є конкретним класом, якщо не інтерфейсом.
user30478

Я не думаю. Інтерфейси не є абстракціями, але можуть бути. Бетонні класи не є абстракціями, але можуть бути. blog.ploeh.dk/2010/12/02/Interfacesarenotabstractions Також у .net є інтерфейс IList. Ви могли б мати рацію, думаю, я поєдную абстракції в домені та абстракції в коді.
Егі,

94

Інкапсуляція : приховування даних за допомогою геттерів, сетерів тощо.

Абстракція : приховування реалізації за допомогою абстрактних класів та інтерфейсів тощо.


6
Кількість голосів, яких отримала ця неправильна відповідь, просто вражає. Хоча абстрактні класи не мають реалізації, їх метою не є абстракція . Їх метою є спадкування , що є абсолютно іншим принципом об’єктно-орієнтованого аналізу та проектування.
displayName

2
Ви хочете сказати, що ми не можемо досягти абстракції без абстрактного класу або інтерфейсу? Це, безумовно, дуже неправильна відповідь.
Вікрам,

1
Кожна функція є інкапсуляція перевірка це також перевірити це на прикладі мобільного телефону .
Shaiju T

50

Приклад абстракції та інкапсуляції Джерело зображення

Абстракція: окреслена лівим верхнім та правим верхнім зображенням кота. Хірург і стара жінка по-різному спроектували (або візуалізували) тварину. Таким же чином ви могли б додати різні функції до класу Cat, залежно від потреби програми. У кожної кішки є печінка, сечовий міхур, серце та легені, але якщо вам потрібно, щоб ваша кішка лише «муркотіла», ви абстрагуєте кішку своєї програми до дизайну зверху ліворуч, а не праворуч угорі.

Інкапсуляція: окреслена кішкою, що стоїть на столі. Ось як повинні бачити кота всі люди, які не є котами . Їм не потрібно хвилюватися, чи справді реалізація кота - це лівий верхній чи верхній правий або навіть комбінація обох.


PS: Перейдіть сюди з цього самого питання, щоб почути повну історію.


7
Найкращий наочний приклад абстракції в ООП, який я знайшов на сьогоднішній день, дякую
Рікардо Діас Морайс

27

Я спробую продемонструвати інкапсуляцію та абстракцію простим способом .. Давайте подивимось ..

  • Об'єднання даних та функцій в єдиний блок (так званий клас) відоме як інкапсуляція. Інкапсуляція, що містить та приховує інформацію про об’єкт, таку як внутрішні структури даних та код.

Інкапсуляція -

  • Приховування складності,
  • Зв'язування даних та функцій разом,
  • Робимо ускладнений метод приватним,
  • Зробити приватну змінну екземпляра приватною,
  • Приховування непотрібних даних та функцій від кінцевого користувача.

Інкапсуляція реалізує абстракцію.

А абстракція -

  • Показуючи необхідне,
  • Дані повинні абстрагуватися від Кінцевого користувача,

Подивимось приклад -

На зображенні нижче показано графічний інтерфейс користувача "Інформація про клієнта, яку слід додати до бази даних".

GUI екрану клієнта

Переглядаючи Зображення, ми можемо сказати, що нам потрібен Клас Клієнта.

Крок 1: Що потрібно моєму Класу клієнтів?

тобто

  • 2 змінні для зберігання коду клієнта та імені клієнта.

  • 1 Функція додавання коду клієнта та імені клієнта до бази даних.

  namespace CustomerContent
    {
       public class Customer
       {
           public string CustomerCode = "";
           public string CustomerName = "";
           public void ADD()
           {
              //my DB code will go here
           }

Зараз лише метод ADD не працює тут поодинці.

Крок -2: Як буде працювати перевірка, функція ADD?

Нам знадобляться код підключення до бази даних та код перевірки (додаткові методи).

     public bool Validate()
     {
    //Granular Customer Code and Name
    return true;
     }

     public bool CreateDBObject()
     {
    //DB Connection Code
    return true;
     }


class Program
{
   static void main(String[] args)
   {
     CustomerComponent.Customer obj = new CustomerComponent.Customer;

     obj.CustomerCode = "s001";
     obj.CustomerName = "Mac";

     obj.Validate();
     obj.CreateDBObject();

     obj.ADD();
    }
}

Тепер немає потреби показувати Додаткові методи ( Validate(); CreateDBObject()[Складний та додатковий метод]) Кінцевому користувачеві. Кінцевому користувачеві потрібно лише бачити та знати про код клієнта, ім’я клієнта та кнопку ADD, яка додасть запис. Кінцевий користувач не дбає про те, ЯК ДОДАТИ Дані до бази даних ?.

Крок -3: Приватні додаткові та складні методи, які не передбачають взаємодії кінцевого користувача.

Таким чином, роблячи ці Ускладнені та Додаткові методи приватними, а не загальнодоступними (тобто приховуючи ці методи) та видаляючи obj.Validate(); obj.CreateDBObject();основну програму в класі, ми досягаємо Інкапсуляції.

Іншими словами, спрощення інтерфейсу для кінцевого користувача - це інкапсуляція.

Тож повний код виглядає так, як показано нижче -

 namespace CustomerContent
 {
     public class Customer
     {
        public string CustomerCode = "";
        public string CustomerName = "";

        public void ADD()
        {
           //my DB code will go here
        }

        private bool Validate()
        {
           //Granular Customer Code and Name
           return true;
        }

        private bool CreateDBObject()
        {
           //DB Connection Code
           return true;
        }


  class Program
  {
     static void main(String[] args)
     {
        CustomerComponent.Customer obj = new CustomerComponent.Customer;

        obj.CustomerCode = "s001";

        obj.CustomerName = "Mac";

        obj.ADD();
   }
}

Короткий зміст:

Крок -1 : Що потрібно моєму класі клієнтів? є Абстракція .

Крок -3 : Крок -3: Приватні додаткові та складні методи, які не передбачають взаємодії з кінцевим користувачем, - це інкапсуляція .

PS - Наведений вище код жорсткий і швидкий.

ОНОВЛЕННЯ: За цим посиланням є відео для пояснення зразка: Яка різниця між абстракцією та інкапсуляцією


1
тепер як буде Validate()і CreateDBObject()телефонує?
varsha

Як би ти зателефонував, Validate()а CreateDBObject()потім ... Я згоден @varsha.
Кріш

1
public void ADD() { Validate(); CreateDBObject(); }
Вікрам

Оманлива відповідь.
user30478

11

Нижче - семестровий курс, перегнаний у кілька абзаців.

Об'єктно-орієнтований аналіз та проектування (OOAD) насправді базується не просто на двох, а на чотирьох принципах. Вони є:

  • Абстракція: означає, що ви включаєте лише ті функції сутності, які потрібні у вашій заявці. Отже, якщо на кожному банківському рахунку є дата відкриття, але вашій програмі не потрібно знати дату відкриття рахунку, тоді ви просто не додаєте поле OpeningDate у свій об’єктно-орієнтований дизайн (класу BankAccount). Абстракція в OOAD не має нічого спільного з абстрактними класами в OOP.

    Відповідно до принципу Абстракції, Ваші сутності є абстракцією того, що вони є в реальному світі. Таким чином, ви розробляєте абстракцію банківського рахунку лише до того рівня деталізації, який необхідний вашій заявці.

  • Спадщина: це скоріше фокус кодування, ніж фактичний принцип. Це позбавляє вас від повторного написання тих функціональних можливостей, які ви написали десь ще. Однак ми думаємо, що між новим кодом, який ви пишете, і старим кодом, який ви хочете повторно використати, має бути зв’язок. В іншому випадку ніхто не заважає вам писати клас Animal, який успадковується від BankAccount , навіть якщо він абсолютно нечутливий.

    Подібно до того, як ви можете успадкувати багатство батьків, ви можете успадкувати поля та методи від батьківського класу. Отже, взяти все, що має батьківський клас, а потім додати щось більше, якщо потрібно, - це успадкування. Не шукайте спадщини у своєму об’єктно-орієнтованому дизайні. Спадщина буде природним чином представляти себе.

  • Поліморфізм: є наслідком успадкування. Успадкування методу від батьків є корисним, але можливість модифікувати метод, якщо того вимагає ситуація, - це поліморфізм. Ви можете реалізувати метод у підкласі з точно таким же підписом, як у батьківському класі, так що при виклику метод із дочірнього класу буде виконаний. Це принцип поліморфізму.

  • Інкапсуляція: передбачає об’єднання відповідних функціональних можливостей та надання доступу лише до необхідних. Інкапсуляція є основою значущого проектування класів в об’єктно-орієнтованому дизайні, шляхом:

    • об'єднання пов'язаних даних та методів; і,
    • оголення лише фрагментів даних та методів, що мають значення для функціонування із зовнішніми суб’єктами.

Інший спрощений відповідь тут .


Люди, які стверджують, що"Абстракція OOAD приводить до абстрактного ключового слова OOP" ...Ну, це неправильно.

Приклад: Коли ви розробляєте університет у програмі з використанням об'єктно-орієнтованих принципів, ви розробляєте лише "абстракцію" університету. Незважаючи на те, що майже в кожному університеті існує один банкомат, що видає готівку, ви можете не враховувати цей факт, якщо це не потрібно для вашої заяви. І тепер, хоча ви створили лише абстракцію університету, вам не потрібно вносити abstractдекларацію про свій клас. Ваш абстрактний дизайн університету буде звичайним класом у вашій заявці.


10

Я думаю, що це дещо різні поняття, але часто вони застосовуються разом. Інкапсуляція - це техніка приховування деталей реалізації від абонента, тоді як абстракція - це більше філософія дизайну, що передбачає створення об’єктів, аналогічних знайомим об’єктам / процесам, що допомагає зрозуміти. Інкапсуляція - це лише один із багатьох методів, який можна використовувати для створення абстракції.

Наприклад, візьмемо "вікна". Вони насправді не є вікнами в традиційному розумінні, це лише графічні квадрати на екрані. Але корисно сприймати їх як вікна. Це абстракція.

Якщо "API Windows" приховує деталі фізичного відображення тексту або графіки в межах вікна, це інкапсуляція.


Чи можете ви надати джерело для підтримки своєї концепції?
Aparan

Ця сторінка Вікіпедії: http://en.wikipedia.org/wiki/Abstraction_(computer_science) містить хороший приклад на Java, з класом під назвою "тварина", який є абстракцією. Клас охоплює той факт, що тварина має "енергетичні резерви" - абонент не повинен цього знати. Натомість абонент просто знає, чи тварина "голодна". Резерви енергії приховані (інкапсульовані).
Mike Panter

Це відповідь, за яку я проголосую. Але приклад абстракції для мене не дуже зрозумілий, оскільки я очікував побачити якийсь абстрактний клас чи речі з інтерфейсу, а не загальну англійську ідею абстракції.
user30478

4

мій 2c

мета інкапсуляції - приховати деталі реалізації від користувача вашого класу, наприклад, якщо ви внутрішньо зберігаєте std :: list елементів у своєму класі, а потім вирішили, що std :: vector буде більш ефективним, ви можете змінити це без користувача турботливий. Тим не менш, спосіб взаємодії з будь-яким контейнером stl завдяки абстракції, і список, і вектор можуть, наприклад, проходити однаково, використовуючи подібні методи (ітератори).


2
при всій повазі я дотримуватимусь своїх пояснень :), тобто інкапсулювання приховування від користувача, абстракція - це більше загальне поняття, як інтерфейс, яким поділяється кілька класів.
AndersK

1
Хм .. Це я сказав у своєму питанні. У кожного свої концепції на цю тему :). Чи можете ви надати надійне посилання для підтвердження свого пояснення?
Aparan


ні, у мене немає посилання, саме так я зрозумів це з різних книг, таких як Code Complete.
AndersK

c-sharpcorner.com/UploadFile/tusharkantagarwal/… plz перевірте ці два посилання та скажіть мені, що прийняти
Aparan

3

Один із прикладів завжди виховувався у мене в контексті абстракції; автоматична та механічна коробка передач на автомобілях. Механічна коробка передач приховує деякі дії перемикання передач, але вам все одно доведеться зчеплюватися і перемикатись як водій. Автоматична коробка передач інкапсулює всі деталі зміни передач, тобто приховує це від вас, і, отже, це більш висока абстракція процесу зміни передач.


"Автоматична коробка передач охоплює всі деталі зміни передач, тобто приховує це від вас" ... насправді саме тому я б сказав, що автоматична та ручна коробка передач на автомобілях є гарним прикладом для ІНКАПСУЛЯЦІЇ! а не для абстракції. автоматична коробка передач - це не абстракція механічної коробки передач, це інша концепція. абстракцією буде, якщо ви скажете, що машині потрібна система передачі потужності, ігноруючи, яким буде фактичний інтерфейс для водія (автоматичним або ручним).
Егі,

Я бачу вашу думку. Але, як я бачу це, абстракція та інкапсуляція пов’язані. Якщо у вас немає інкапсуляції, у вас немає абстракції. Завдяки інкапсуляції ви можете знайти більш абстрактні поняття, тому автоматична коробка передач є кращою абстракцією, ніж механічна коробка передач. Можливо, вам навіть не потрібна концепція трансмісії, можливо, вам потрібна лише концепція автомобіля, що рухається вперед, який би містив у собі всі внутрішні роботи автомобіля.
Lorentz Vedeler

1
Я абсолютно згоден з вашим останнім твердженням. Ви можете абстрагувати все, поки ніхто більше не уявляє, про що це насправді. але я не згоден з вашим першим твердженням. Ви можете практикувати інкапсуляцію без абстракції, наприклад, створивши програму лише з одним великим класом, який обробляє все і приховує всі деталі реалізації від клієнта. а абстракція без інкапсуляції також можлива шляхом створення програми з класів, які є малими і несуть одну відповідальність, але не приховують жодних деталей реалізації або будь-якого недійсного стану.
Егі,

1

Інкапсуляція: приховування деталей реалізації (ПРИМІТКА: дані І / АБО методи), таких, щоб їм було доступно лише те, що розумно читається / доступне для запису / використання зовнішніми, а все інше безпосередньо "недоторкане".

Абстракція: Іноді це стосується конкретно типу, який неможливо створити, і який забезпечує шаблон для інших типів, які можуть бути, як правило, шляхом підкласу. Більш загально, "абстракція" означає виготовлення / наявність чогось менш детального, менш конкретного, менш детального.

Існує деяка схожість, що накладається між поняттями, але найкращий спосіб запам’ятати її такий: інкапсуляція - це більше приховування деталей, тоді як абстракція - це узагальнення деталей.


1

Абстракція та інкапсуляція заплутані терміни і залежать один від одного. Візьмемо це на прикладі:

public class Person
    {
        private int Id { get; set; }
        private string Name { get; set; }
        private string CustomName()
        {
            return "Name:- " + Name + " and Id is:- " + Id;
        }
    }

Коли ви створювали клас Person, ви робили інкапсуляцію, записуючи властивості та функції разом (Id, Name, CustomName). Ви виконуєте абстракцію, коли ви виставляєте цей клас клієнту як

Person p = new Person();
p.CustomName();

Ваш клієнт нічого не знає про ідентифікатор та ім’я в цій функції. Тепер якщо ваш клієнт хоче знати і прізвище, не порушуючи виклик функції. Ви робите інкапсуляцію, додаючи ще одне властивість до класу Person, як цей.

public class Person
        {
            private int Id { get; set; }
            private string Name { get; set; }
            private string LastName {get; set;}
            public string CustomName()
            {
                return "Name:- " + Name + " and Id is:- " + Id + "last name:- " + LastName;
            }
        }

Подивіться, навіть додавши зайве властивість у класі, ваш клієнт не знає, що ви зробили з вашим кодом. Тут ви зробили абстракцію.


0

Як я знаю, інкапсуляція приховує дані класів у собі та робить їх доступними лише через сетери / геттери, якщо до них потрібно отримати доступ із зовнішнього світу.

Абстракція - це дизайн класу сам по собі.

Означає, як Ви створюєте своє дерево класів, які методи є загальними, які успадковуються, які можна замінити, які атрибути є лише на приватному рівні або на захищених, як Ви створюєте своє дерево успадкування класів, Чи використовуєте Ви final класи, класи абстракції, реалізація інтерфейсу.

Абстракція більше відповідає фазі проектування, тоді як інкапсуляція також включається у фазу розвитку.


0

Я думаю про це таким чином, інкапсуляція приховує те, як щось робиться. Це може бути одна або багато дій.

Абстракція пов'язана з "чому", я інкапсулюю це перше місце.

Я в основному кажу клієнтові: "Вам не потрібно знати багато про те, як я обробляю платіж та обчислюю вартість доставки тощо. Я просто хочу, щоб ви сказали мені, що хочете" Оформити замовлення ", і я подбаю про вас . "

Таким чином я інкапсулював деталі, узагальнивши (абстрагуючи) до запиту Checkout.

Я справді думаю, що абстрагування та інкапсуляція поєднуються.


0

Абстракція

На Java абстракція означає приховування інформації до реального світу. Він встановлює договір між стороною про те, що "що нам робити, щоб скористатися послугою".

Наприклад, при розробці API, лише абстрактна інформація сервісу була розкрита світові, а не фактична реалізація. Інтерфейс у Java може допомогти досягти цієї концепції дуже добре.

Інтерфейс забезпечує договір між сторонами, наприклад, виробником та споживачем. Виробник виробляє товар, не повідомляючи споживачеві, як виготовляється товар. Але через інтерфейс Виробник повідомляє усім споживачам, який товар можна купити. За допомогою абстракції виробник може продавати товар своїм споживачам.

Інкапсуляція:

Інкапсуляція - це один рівень абстракції. Одна і та ж товарна компанія намагається захистити інформацію одна від одної виробничої групи. Наприклад, якщо компанія виробляє вино та шоколад, інкапсуляція допомагає захищати інформацію про те, як кожен продукт виготовляється один від одного.

  1. Якщо у мене є індивідуальний пакет для вина та інший для шоколаду, і якщо всі класи оголошені в пакеті як модифікатор доступу за замовчуванням, ми надаємо інкапсуляцію рівня пакету для всіх класів.
  2. У межах пакету, якщо ми оголошуємо кожен поданий клас (поле-член) приватним і маємо відкритий метод доступу до цих полів, таким чином забезпечуючи інкапсуляцію на рівні класу до цих полів
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.