Может ли кто-нибудь предоставить простой пример, объясняющий разницу между динамическим и статическим полиморфизмом в Java?
java
oop
polymorphism
overloading
overriding
Прабхакар Мантена
источник
источник
Ответы:
Полиморфизм
1. Статическое связывание / связывание во время компиляции / раннее связывание / перегрузка метода (в том же классе)
2. Динамическая привязка / привязка во время выполнения / поздняя привязка / переопределение метода (в разных классах)
пример перегрузки:
преобладающий пример:
источник
Animal reference but Dog object
, почему мы не можем использоватьDog reference and dog object
?Перегрузка метода была бы примером статического полиморфизма
тогда как переопределение было бы примером динамического полиморфизма.
Потому что в случае перегрузки во время компиляции компилятор знает, какой метод связать с вызовом. Однако он определяется во время выполнения для динамического полиморфизма
источник
Динамический (во время выполнения) полиморфизм - это полиморфизм, существующий во время выполнения. Здесь компилятор Java не понимает, какой метод вызывается во время компиляции. Только JVM решает, какой метод вызывается во время выполнения. Перегрузка метода и переопределение метода с использованием методов экземпляра являются примерами динамического полиморфизма.
Например,
Рассмотрим приложение, которое сериализует и десериализует различные типы документов.
У нас может быть «Документ» в качестве базового класса и производные от него классы различных типов документов. Например, XMLDocument, WordDocument и т. Д.
Класс документа будет определять методы «Serialize ()» и «De-serialize ()» как виртуальные, и каждый производный класс будет реализовывать эти методы по-своему на основе фактического содержимого документов.
Когда различные типы документов необходимо сериализовать / десериализовать, на объекты документа будет ссылаться ссылка на класс (или указатель) «Документ», а при вызове метода «Serialize ()» или «De-serialize ()» на нем вызываются соответствующие версии виртуальных методов.
Статический (во время компиляции) полиморфизм - это полиморфизм, проявляемый во время компиляции. Здесь компилятор Java знает, какой метод вызывается. Перегрузка методов и переопределение методов с использованием статических методов; переопределение метода с использованием частных или конечных методов являются примерами статического полиморфизма
Например,
У объекта сотрудника может быть два метода print (): один не принимает аргументов, а другой принимает строку префикса, которая будет отображаться вместе с данными сотрудника.
С учетом этих интерфейсов, когда метод print () вызывается без каких-либо аргументов, компилятор, глядя на аргументы функции, знает, какая функция должна быть вызвана, и соответственно генерирует объектный код.
Для более подробной информации прочтите «Что такое полиморфизм» (Google it).
источник
На этой картинке хорошо видно, что является обязательным.
На этом рисунке вызов «a1.methodOne ()» привязан к соответствующему определению methodOne (), а вызов «a1.methodTwo ()» привязан к соответствующему определению methodTwo ().
Для каждого вызова метода должно быть правильное определение метода. Это правило в java. Если компилятор не видит правильного определения метода для каждого вызова метода, он выдает ошибку.
Теперь перейдем к статической привязке и динамической привязке в java.
Статическая привязка в Java:
,
Статическое связывание можно продемонстрировать, как показано на рисунке ниже.
На этом рисунке 'a1' - это ссылочная переменная типа Class A, указывающая на объект класса A. 'a2' также ссылочная переменная типа класса A, но указывающая на объект класса B.
Во время компиляции при связывании компилятор не проверяет тип объекта, на который указывает конкретная ссылочная переменная. Он просто проверяет тип ссылочной переменной, через которую вызывается метод, и проверяет, существует ли определение метода для него в этом типе.
Например, для вызова метода «a1.method ()» на изображении выше компилятор проверяет, существует ли определение метода для method () в классе A. Поскольку «a1» является типом класса A. Аналогично, для вызова метода «a2.method ()» он проверяет, существует ли определение метода для method () в классе A. Поскольку «a2» также является типом класса A. Он не проверяет, на какой объект указывают «a1» и «a2». Этот тип привязки называется статической привязкой.
Динамическое связывание в Java:
Во время выполнения для привязки используются реальные объекты. Например, для вызова «a1.method ()» на рисунке выше будет вызван метод () фактического объекта, на который указывает «a1». Для вызова «a2.method ()» будет вызван метод () фактического объекта, на который указывает «a2». Этот тип привязки называется динамической привязкой.
Динамическое связывание приведенного выше примера можно продемонстрировать, как показано ниже.
Ссылка на статическую привязку и динамическую привязку в java
источник
Полиморфизм: полиморфизм - это способность объекта принимать разные формы. Наиболее распространенное использование полиморфизма в ООП происходит, когда ссылка на родительский класс используется для ссылки на объект дочернего класса.
Динамическое связывание / полиморфизм времени выполнения:
Полиморфизм времени выполнения, также известный как переопределение метода. В этом механизме вызов переопределенной функции разрешается во время выполнения.
Вывод:
Метод внутреннего старта автомобиля
Статическое связывание / полиморфизм времени компиляции:
Решение о том, какой метод вызывать, решается только во время компиляции.
Вывод: метод сортировки внутри коллекции
источник
перегрузка метода является примером статического полиморфизма времени компиляции, поскольку привязка метода между вызовом метода и определением метода происходит во время компиляции и зависит от ссылки на класс (ссылка создается во время компиляции и переходит в стек).
переопределение метода является примером динамического полиморфизма времени выполнения, потому что привязка метода между вызовом метода и определением метода происходит во время выполнения и зависит от объекта класса (объект, созданный во время выполнения, отправляется в кучу).
источник
Проще говоря:
Статический полиморфизм : одно и то же имя метода перегружено с другим типом или количеством параметров в одном классе (разные сигнатуры). Целевой вызов метода разрешается во время компиляции.
Динамический полиморфизм : один и тот же метод переопределяется одинаковой сигнатурой в разных классах. . Тип объекта, для которого вызывается метод, неизвестен во время компиляции, но будет определен во время выполнения.
Обычно перегрузка не рассматривается как полиморфизм.
Со страницы руководства по Java :
источник
Generally overloading won't be considered as polymorphism.
не могли бы вы уточнить этот момент.Перегрузка метода известна как статический полиморфизм, а также известна как полиморфизм времени компиляции или статическое связывание. поскольку вызовы перегруженных методов разрешаются компилятором во время компиляции на основе списка аргументов и ссылки, по которой мы вызываем метод.
И методы Перекрытие известно как Dynamic полиморфизм или просто полиморфизм или время выполнения метод отправка или динамическое связывание , поскольку переопределяется метод вызов разрешаются во время выполнения.
Чтобы понять, почему это так, давайте возьмем пример
Mammal
иHuman
классЯ включил вывод, а также байт-код в следующие строки кода
И, посмотрев на приведенный выше код, мы видим, что байт-коды humanMammal.speak (), human.speak () и human.speak («хинди») совершенно разные, потому что компилятор может различать их на основе списка аргументов. и ссылка на класс. Вот почему перегрузка метода известна как статический полиморфизм. .
Но байт-код для anyMammal.speak () и humanMammal.speak () такой же, потому что в соответствии с компилятором оба метода вызываются по ссылке Mammal, но вывод для обоих вызовов методов отличается, потому что во время выполнения JVM знает, какой объект удерживает ссылка, и вызывает JVM метод объекта, поэтому переопределение метода известно как динамический полиморфизм.
Таким образом, из приведенного выше кода и байт-кода ясно, что на этапе компиляции метод вызова рассматривается из ссылочного типа. Но во время выполнения метод будет вызван из объекта, который содержит ссылка.
Если вы хотите узнать больше об этом, вы можете прочитать больше о том, как JVM обрабатывает перегрузку и переопределение методов внутренне .
источник
Статический полиморфизм: решение о том, какой метод выполнить, принимается во время компиляции. Примером этого может быть перегрузка метода.
Динамический полиморфизм: решение о выборе метода для выполнения устанавливается во время выполнения. Примером этого может быть переопределение метода.
источник
Полиморфизм относится к способности объекта вести себя по-разному для одного и того же триггера.
Статический полиморфизм (полиморфизм времени компиляции)
Динамический полиморфизм (полиморфизм времени выполнения)
источник
Полиморфизм времени компиляции (статическое связывание / раннее связывание): в статическом полиморфизме, если мы вызываем метод в нашем коде, то определение того, какое определение этого метода должно быть вызвано на самом деле, разрешается только во время компиляции.
(или)
Во время компиляции Java знает, какой метод вызывать, проверяя сигнатуры методов. Итак, это называется полиморфизмом времени компиляции или статическим связыванием.
Динамический полиморфизм (полиморфизм позднего связывания / времени выполнения): во время выполнения Java ожидает, пока среда выполнения не определит, на какой объект фактически указывает ссылка. Разрешение метода было принято во время выполнения, поэтому мы называем это полиморфизмом времени выполнения.
источник
Рассмотрим код ниже:
Теперь, глядя на код, вы никогда не сможете сказать, какая реализация methodA () будет выполнена, потому что это зависит от того, какое значение пользователь задает во время выполнения. Таким образом, только во время выполнения решается, какой метод будет вызван. Следовательно, полиморфизм времени выполнения.
источник
Перегрузка метода - это полиморфизм времени компиляции, давайте рассмотрим пример, чтобы понять концепцию.
В этом примере у Person есть метод eat, который означает, что он может съесть пиццу или лапшу. Что метод eat перегружен, когда мы компилируем этот Person.java, компилятор разрешает вызов метода "e.eat (noodles) [который находится в строке 6] с определением метода, указанным в строке 8, то есть это метод, который принимает лапшу в качестве параметра и весь процесс выполняется компилятором, поэтому это полиморфизм времени компиляции.Процесс замены вызова метода определением метода называется связыванием, в этом случае это выполняется компилятором, поэтому он вызывается как раннее связывание.
источник
Следуя ответу Нареша, динамический полиморфизм является только «динамическим» в Java из-за наличия виртуальной машины и ее способности интерпретировать код во время выполнения, а не код, выполняющийся изначально.
В C ++ это должно быть разрешено во время компиляции, если он компилируется в собственный двоичный файл с использованием gcc, очевидно; однако скачки и переходы во время выполнения в виртуальной таблице по-прежнему называются «поисковыми» или «динамическими». Если C наследует B, и вы объявляете , c уже будет указывать на внешний объект C, и указатель будет передан в C :: method1 () в текстовом сегменте. См .: http://www.programmersought.com/article/2572545946/
B* b = new C(); b->method1();
, компилятор разрешит b, чтобы указать на объект B внутри C (для простого класса наследует ситуацию класса, объект B внутри C и C будет начинаться с того же адреса памяти, поэтому ничего необходимо сделать; он будет указывать на vptr, который они оба используют). Если C наследует B и A, таблица виртуальных функций объекта A внутри записи C для метода1 будет иметь преобразователь, который смещает указатель на начало инкапсулирующего объекта C, а затем передает его в реальный A :: method1 () в текстовом сегменте, который C переопределил. ДляC* c = new C(); c->method1()
В java для
B b = new C(); b.method1();
виртуальная машина может динамически проверять тип объекта в паре с b, передавать правильный указатель и вызывать правильный метод. Дополнительный шаг виртуальной машины устраняет необходимость в таблицах виртуальных функций или типе, определяемом во время компиляции, даже если он может быть известен во время компиляции. Это просто другой способ сделать это, который имеет смысл, когда задействована виртуальная машина, а код компилируется только в байт-код.источник