В чем разница между абстракцией и полиморфизмом - PullRequest
31 голосов
/ 15 декабря 2008

Кажется, я не очень хорошо понимаю две концепции ООП. Не могли бы вы объяснить, что такое абстракция и полиморфизм , желательно с реальными примерами и кодом?

Спасибо.

Ответы [ 11 ]

26 голосов
/ 15 декабря 2008

Абстракция

Представьте себе класс дроби:

class fraction:
    int denominator
    int numerator

Теперь два объекта этого:

fraction(obj1): denominator=-1 numerator=-1
fraction(obj2): denominator=1  numerator=1

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

[1]=(1, 1), (-1, -1), (5, 5), ...
[2]=(2, 4), (-2, -4), ...
...

И есть функция абстракции, которая абстрагирует внутренние детали извне:

f((1, 1)) = [1]
f((-1, -1)) = [1]

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

Полиморфизм

Представьте себе ручку и два производных класса:

class pen:
    void draw(int x, int y)

class pen_thin extends pen:
    void draw(int x, int y) { color(x, y) = green; }

class pen_thick extends pen:
    void draw(int x, int y) { color(x, y) = green; 
                              color(x, y+1) = green; }
and two objects:
    pen_thin(p1)
    pen_thick(p2)

Обе ручки могут рисовать. Ваша общая "ручка" не может нарисовать себя. Это просто интерфейс к pen_thin, pen_thick и множеству других ручек. Вы говорите: obj1.draw (1, 0); и то, является ли obj1 толстым или тонким пером, не имеет значения как для пользователя, так и для компилятора во время компиляции. Звонок ведет себя полиморфно. Это динамический полиморфизм (происходит во время выполнения), и это обычно имеют в виду люди. Статический полиморфизм происходит во время компиляции:

class colorizer:
    void colorize(shirt s)
    void colorize(pants p)

Это называется перегрузкой. Вы звоните obj.colorize(something). Если вы называете это ссылкой на рубашку, она будет называть версию с рубашкой. И если вы называете это со ссылкой на брюки, он будет называть версию штаны. Выбор сделан здесь во время компиляции .

13 голосов
/ 15 декабря 2008

Эти две являются одними из наиболее важных характеристик объектно-ориентированной парадигмы.

Абстракция.

Объектная ориентация моделирует программное обеспечение как объекты реального мира. Однако было бы слишком сложно (и бесполезно) смоделировать ВСЕ свойства, которые может иметь Клиент, или все свойства, которые имеет Сотрудник.

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

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

полиморфизм.

Объекты могут вести себя по-разному в зависимости от «типа» при сохранении одного и того же интерфейса.

Что это значит?

Например, система интернет-магазина может иметь два подкласса Сотрудника

А) Внутренние сотрудники.

B) Подрядчики

и метод расчета скидки при внутренних покупках

Скидка внутреннего сотрудника рассчитывается следующим образом: 10% + 2% за каждый год работы в компании + 2% за каждого .. ммхх ребенок

Скидка подрядчика составляет 10%

Следующий код для расчета суммы оплаты:

 public Amount getAmountToPay( Product product, Employee internalCustomer ) { 
      Amount amount = product.getPrice();
      amount.applyDiscount( internalCustomer.getDiscount() );
      return amount;
 }

даст разные результаты для двух разных типов сотрудников

class Employee { 
    public int getDiscount();
}


class InternalEmployee extends Employee { 
     public int getDiscount() { 
        return 10 + 2 * getWorkedYears() + 2 * getNumberOfChilds();
     }
 }

 class Contractor extends Employee { 
      public int getDiscount() { 
          return 10;
     }
 }

Это полиморфизм в действии. Вместо того, чтобы иметь что-то вроде

 Amount amount = product.getPrice();

 if( employee.isContractor() ) { 
      amount.applyDiscount( 10 );
 } else if( employee.isSomthingElse() ) {
      amount.applyDiscount( 10 * 2 * getYrs() + 2 * getChilds() );
 } else if ( employee.contidions, condigions, conditions ) {
      amount.applyDiscount( getSomeStrageRuleHere() );
 }

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

      Amount amount = product.getPrice();
      amount.applyDiscount( internalCustomer.getDiscount() );
      return amount;

Кстати, в этом примере «Количество» является абстракцией реальной жизненной концепции, которая также может быть представлена ​​в виде двойного или целого числа, но, возможно, у нас есть методы интереса внутри, которые были бы лучше, если бы они были установлены в его собственный класс.

Надеюсь, это поможет.

11 голосов
/ 15 декабря 2008

Абстракция и полиморфизм являются критическими понятиями, которые ни в коем случае не ограничиваются ОО. В дополнение к путанице, слово «абстракция» используется несколькими способами. Вот быстрый шпаргалка с одним примером:

  • Абстракция данных означает сокрытие информации . Обычно скрыто представление структуры данных. Пример: я реализую наборы, но я не говорю вам, представлен ли набор в виде списка, сбалансированного двоичного дерева или несбалансированного двоичного дерева. Сделано правильно, Я могу изменить представление, не нарушая ваш код .

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

Очевидно, вы можете определить класс, который является как абстрактным, так и полиморфным.

Полиморфизм еще более запутан, потому что существует два способа реализации полиморфизма . В параметрическом полиморфизме вы можете повторно использовать набор со значениями любого типа или, возможно, любого типа, удовлетворяющего некоторому ограничению. Наиболее очевидные примеры : C ++ шаблоны ; если ты пишешь

class Set <T> { ... }

Тогда T - это тип объектов, содержащихся в наборе (обозначение <T> указывает на так называемый «параметр типа», что делает его параметрическим полиморфизмом).

В полиморфизме подтипа вы можете повторно использовать наборы только с объектами, типы которых являются подтипами определенного типа. Например, вы можете создавать наборы только из объектов, предлагающих метод «меньше или равно». В настоящем объектно-ориентированном языке, таком как Smalltalk или Ruby, который предлагает так называемую типизацию утки (мы, теоретики с острым умом, иногда называем это поведенческим подтипом ), присутствие метода достаточно хорошо. В таких языках, как Java или C ++, которые связывают подтипы с наследованием , использование полиморфизма может быть ограничено подклассами определенного класса . (Java еще больше путает проблему, используя одну форму подтипов в классах и другую в интерфейсах.)

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

Итак, вы чувствуете себя лучше, если вас смущают?

6 голосов
/ 15 декабря 2008

Абстракция относится к представлению основных функций без включения подробностей фона или объяснений. Классы используют понятие абстракции и определяются как список абстрактных атрибутов.

Одним из примеров программной абстракции является метод Java Object.equals(Object o). Вы знаете, что он будет сравнивать этот объект с объектом, переданным в качестве параметра, но вы не знаете и не должны знать, как именно он будет реализован (если вы не являетесь реализатором класса). *

Полиморфизм означает способность принимать более одной формы. Метод может иметь различное поведение в разных случаях. Поведение зависит от типов данных, используемых в операции.

Один из классических примеров полиморфизма использует дерево наследования с корнем в классе Animal. Все Animal имеют метод makeNoise(), но класс Dog и класс Cat реализуют его по-разному. Это позволяет вам ссылаться на любых собак и кошек, используя ссылочный тип Animal.

Animal a = new Dog();
Animal b = new Cat();

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

3 голосов
/ 15 декабря 2008

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

3 голосов
/ 15 декабря 2008

Оба термина интенсивно используются в объектно-ориентированном программировании, но они конкретно не ограничены этим контекстом.

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

Полиморфизм также является обобщением, но происходит в контексте времени выполнения. Куча разных типов объектов полиморфна, если есть какой-то способ доступа к ним, когда они неотличимы друг от друга. То есть все объекты выглядят и чувствуют то же самое, даже если это не так. Целью этого является значительное сокращение кода; Вы можете написать одно обобщенное решение, чтобы избавиться от записи всех различных перестановок для каждого отдельного типа. Если вы пишете графическую библиотеку, вам лучше написать некоторый абстрактный код для обработки «фигур», а затем написать код для каждого типа, такого как круги, квадраты и т. Д.

Оба эти термина сосредоточены вокруг свойств в коде, которые позволят программистам делать больше с меньшими затратами. Чем меньше кода, тем меньше ошибок, он более стабилен и его легче поддерживать. Альтернативой является использование «грубой силы», чтобы отбросить миллионы и миллионы строк очень специфического (и очень хрупкого) кода. Большее количество кода сложнее исправить и гораздо сложнее поддерживать его в актуальном состоянии.

Paul.

2 голосов
/ 08 сентября 2016

Абстракция и полиморфизм похожи по своей природе с другой целью.

Например.

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

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

Теперь, здесь, Полиморфизм - это разные способы, которыми индивидуальная лицензия распределяется властью разным людям, некоторые выдаются для легких транспортных средств, а некоторые для тяжелых и некоторые для коммерческих транспортных средств, в соответствии с различными требованиями. Здесь Лицензия - это базовый класс , а другие виды лицензий - это его дочерние классы, также подчиняющиеся is-a . Коммерческая лицензия - это лицензия.

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

0 голосов
/ 03 июня 2019

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

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

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

Однако при использовании в качестве отдельного термина для описания характеристик ООП абстракция должна пониматься как правильное представление обсуждаемой системы в форме подходящей иерархии классов. Таким образом, абстракция является результатом умственных процессов дизайнера, которые завершаются соответствующим дизайном для классов, которые будут использоваться в программе. Цитировать (отлично!) Сообщение , которое можно найти в блоге javarevisited :

... Абстракция скрывает детали на уровне проекта, а инкапсуляция скрывает детали на уровне реализации.

Хотя приведенное выше утверждение является верным, я считаю, что часть «скрытие подробностей» искажена - я бы перефразировал ее как что-то вроде

Абстракция касается деталей проекта, решая, как должна выглядеть иерархия классов, Инкапсуляция скрывает детали осуществление * 1025. *

Чтобы быть справедливым по отношению к автору, именно эта идея прекрасно сочетается с его статьей. Термин «абстракция» с таким значением также встречается в хороших книгах, таких как Head First Object-Oriented Analysis and Design , и я цитирую утверждение оттуда:

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

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

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

0 голосов
/ 24 января 2019

Проще говоря, абстракция является концептуальной, а поли - поведенческой. Чтобы добиться абстракции в ООП, вам нужен Poly.

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

0 голосов
/ 26 ноября 2015

P.S .: недавно начал изучать java ответ основан на моих наблюдениях, пожалуйста, поправьте меня, если я ошибаюсь.

Абстракция и полиморфизм в основном в глубине делают почти одинаковую работу в программировании.

Давайте возьмем машину для примера ..

не имеет значения, будь то мини-фургон Ford, экзотический Ferrari, внедорожник Land-Rover или седан BMW, все они следуют базовому дизайну автомобиля: двигатель, руль, коробка передач, фары , индикаторы и список можно продолжить. что отличает их, так это их специфические реализации, например, у Ferrari может быть более мощный двигатель, чем у минивэна, у внедорожника может быть другая коробка передач следовательно, автомобиль (суперкласс здесь) был реализован подклассами (седан, внедорожник, мини-фургон, экзотика) Это полиморфизм , основная идея наследуется или реализуется путем добавления другой спецификации. четырехколесное транспортное средство (суперкласс), реализуемое в различных формах (подклассах)

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

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

Теперь перейдем к кодированию Part.

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

abstract class car {
  abstract void gear();
}

class sedan extends car {
 public void gear()
 {
  //complete the method
 }
}

также вы не можете создавать объекты абстрактных классов, потому что класс не завершен. Тем не менее, эти абстрактные классы могут иметь статические методы, аргументы, конкретные методы, НО для того, чтобы они были абстрактными, им нужен один абстрактный метод. Таким образом, один базовый абстрактный суперкласс реализован в других подклассах, где они завершают его Глядя на объявление метода, мы можем оценить, что именно делает метод, что он собирается вернуть. Но мы не знаем, как именно будет реализован абстрактный метод.

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

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

HENCE, abstract в основном помогает полиморфизму.

...