В чем разница между абстракцией и полиморфизмом

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

Спасибо.

15.12.2008 01:37:43
Я не думаю, что это звучит как домашняя работа, я бы сказал, что ему / ей трудно понять.
Nathan W 15.12.2008 01:43:22
Это не домашняя работа, но когда я обсуждал со своей командой, эти концепции стали немного похожи. Вот почему они меня смущают. Абстракция не ссылается на какую-либо конкретную деталь чего-либо, а полиморфизм относится к методам разных объектов, которые имеют одинаковые, но выполняют разные задачи. Я прав?
Sambath Prum 15.12.2008 01:56:43
11 ОТВЕТОВ

очень просто.

  1. Абстракция есть абстракция. Класс «Студент» - это абстракция настоящего студента.

  2. Полиморфизм - это когда один класс представляет другой, чтобы пользователь не заметил. Это может произойти, когда классы реализуют один и тот же интерфейс или один класс наследуется от другого. Класс HighSchoolStudent является производным от класса Student. Когда класс 'Teacher' вызывает метод #attendance для объекта, он может не знать, принадлежит ли этот объект классу 'Student' или классу HighSchoolStudent.

-4
15.12.2008 01:47:18

абстракция

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

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). Если вы называете это с ссылкой на рубашку, он будет называть версию с рубашкой. И если вы называете это со ссылкой на брюки, он будет называть версию штаны. Выбор сделан здесь во время компиляции .

27
15.12.2008 02:23:22

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

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

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

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

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

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

6
15.12.2008 01:58:55

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

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

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

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

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

class Set <T> { ... }

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

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

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

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

12
15.12.2008 03:17:18
Итак, в чем разница между абстракцией данных и специальным полиморфизмом?
Aadit M Shah 13.07.2019 05:19:28

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

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

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

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

Павел.

4
15.12.2008 04:27:46

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

3
15.12.2008 05:09:39

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

Абстракция.

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

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

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

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

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

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

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

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

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

И способ расчета скидки на внутренние покупки

Скидка внутреннего сотрудника рассчитывается как: 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;

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

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

14
21.02.2014 11:46:17
Отличное объяснение!
Student 29.12.2013 21:32:30

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

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

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

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

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

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

Теперь перейдем к части кода.

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

abstract class car {
  abstract void gear();
}

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

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

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

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

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

0
26.11.2015 06:52:12

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

Например

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

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

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

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

2
8.09.2016 13:53:13

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

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

0
23.01.2019 23:00:46

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

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

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

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

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

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

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

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

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

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

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

1
2.06.2019 22:01:33