it-roy-ru.com

В чем основное различие между наследованием и полиморфизмом?

Я был задан с этим вопросом в конце экзамена по открытию книги сегодня и обнаружил, что потерян. Я читал Head first Java, и оба определения казались абсолютно одинаковыми. Мне было просто интересно, какова ГЛАВНАЯ разница для моего собственного разума. Я знаю, что есть ряд подобных вопросов, но ни один из них, которые я видел, не дает однозначного ответа.

139
Darren Burgess

Наследование - это когда «класс» происходит от существующего «класса». Поэтому, если у вас есть класс Person, то у вас есть класс Student, который расширяет Person, Student наследует все, что есть у Person. Есть некоторые детали относительно модификаторов доступа, которые вы помещаете в поля/методы в Person, но это основная идея. Например, если у вас есть личное поле в Person, Student не увидит его, потому что его закрытые и частные поля не видны подклассам.

Полиморфизм имеет дело с тем, как программа решает, какие методы она должна использовать, в зависимости от того, что она имеет. Если у вас есть Person, который имеет метод read, и у вас есть Student, который расширяет Person, который имеет собственную реализацию read, то какой метод вызывается, определяется для вас во время выполнения, в зависимости от того, есть ли у вас Person или Student , Это немного сложно, но если вы делаете что-то вроде

Person p = new Student();
p.read();

метод read на Student вызывается. Это полиморфизм в действии. Вы можете выполнить это назначение, потому что Student это Person, но среда выполнения достаточно умна, чтобы знать, что фактический тип p - Student .

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

250
hvgotcodes

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

Полиморфизм относится к изменению поведения суперкласса в подклассе.

170
Ted Hopp

Полиморфизм : Способность обрабатывать объекты разных типов одинаковым образом. Пример: Жираф и Крокодил - оба Животные, и животные могут Move. Если у вас есть экземпляр Animal, вы можете вызвать Move, не зная или не заботясь о том, что это за животное.

Наследование : Это один из способов достижения как полиморфизма, так и повторного использования кода одновременно.

Другие формы полиморфизма : Существуют другие способы достижения полиморфизма, такие как интерфейсы, которые обеспечивают только полиморфизм, но не повторное использование кода (иногда код совсем другой, например, Move для Snake будет совсем другим от Move для собаки, и в этом случае интерфейс будет лучшим полиморфным выбором в этом случае.

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

58
Davy8

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

Кроме того, полиморфизм имеет дело с вызовом метода, тогда как наследование также описывает элементы данных и т.д.

17
Chris Thompson

В Java эти два тесно связаны. Это потому, что Java использует метод для вызова метода, который называется «динамическая диспетчеризация». Если у меня есть

public class A {
  public void draw() { ... }
  public void spin() { ... }
}

public class B extends A {
  public void draw() { ... }
  public void bad() { ... }
}

...

A testObject = new B();

testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A

Затем мы видим, что B наследует spin от A. Однако, когда мы пытаемся манипулировать объектом, как если бы это был тип A, мы все равно получаем поведение B для draw. Поведение draw является полиморфным.

В некоторых языках полиморфизм и наследование не так тесно связаны. Например, в C++ функции, не объявленные как виртуальные, наследуются, но не отправляются динамически, поэтому вы не получите такое полиморфное поведение даже при использовании наследования. 

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

12
ccoakley

Полиморфизм: Предположим, вы работаете в компании, которая продает ручки. Таким образом, вы создаете очень хороший класс под названием «Ручка», который обрабатывает все, что вам нужно знать о ручке. Вы пишете все виды классов для выставления счетов, доставки, создания счетов, все с помощью класса Pen. Приходит босс и говорит: «Отличная новость! Компания растет, и мы сейчас продаем книги и компакт-диски!» Не очень хорошая новость, потому что теперь вы должны изменить каждый класс, который использует Pen, чтобы также использовать Book & CD. Но что, если вы изначально создали интерфейс под названием «SellableProduct», а Pen реализовал этот интерфейс. Тогда вы могли бы написать все свои классы доставки, выставления счетов и т.д., Чтобы использовать этот интерфейс вместо Pen. Теперь все, что вам нужно сделать, это создать новый класс Book & CompactDisc, который реализует интерфейс SellableProduct. Из-за полиморфизма все остальные классы могут продолжать работать без изменений! Есть смысл?

Таким образом, это означает использование Наследования, которое является одним из способов достижения полиморфизма.

Полиморфизм возможен в классе/интерфейсе, но наследование всегда между 2 OR и более классами/интерфейсами. Наследование всегда соответствует отношениям "есть-а", тогда как оно не всегда соответствует полиморфизму (который может соответствовать отношениям "есть-а"/"имеет-а").

12
AmitK

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

Например.

// This assignment is possible because B extends A
A a = new B();
// polymorphic call/ access
a.foo();

-> Несмотря на то, что статический/декларационный тип a равен A, фактический динамический тип/тип времени выполнения равен B, и, следовательно, a.foo () будет выполнять foo, как определено в B, а не в A.

6
Puce

Документация Oracle процитировала разницу точно. 

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

полиморфизм:полиморфизм относится к принципу в биологии, в котором организм или вид могут иметь много различных форм или стадий. Этот принцип также может быть применен к объектно-ориентированному программированию и таким языкам, как язык Java. Подклассы класса могут определять свое собственное уникальное поведение и, тем не менее, совместно использовать некоторые из тех же функций родительского класса.

полиморфизм неприменимо для полей. 

Связанный пост:

Полиморфизм против переопределения против перегрузки

3
Ravindra babu

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

3
laz

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

3
avenger12

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

Например, пример полиморфизма Java:

 enter image description here

Наследование позволяет производным классам совместно использовать интерфейсы и код своих базовых классов. Это происходит во время время компиляции.

Например, все классы в платформе Java являются потомками объекта (изображение любезно предоставлено Oracle):

 enter image description here

Чтобы узнать больше о наследовании Java и полиморфизме Java

1
Stas

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

0
Alireza Rahmani Khalili

Основное назначение полиморфизм: создание ссылочной переменной для суперкласса и удержание подкласса объекта =>, который объект может выполнять несколько вариантов поведения

В наследование, подкласс наследуют свойства суперкласса.

0
satya

Наследование - это когда класс A наследует все нестатические защищенные/публичные методы/поля от всех своих родителей до Object.

0
Cosmin Cosmin

Полиморфизм достигается путем Наследование в Java.

public class Animal {}
public interface Herbivore {}
public interface Carnivore {}
public interface Pet {}

public class Hamster extends Animal implements Herbivore implements Pet () {}
public class Cat extends Animal implements Carnivore implements Pet () {}

Hamster класс наследуетStructureот Animal, Herbivore и Pet, чтобы показатьПолиморфный бихевиоризмот домашнего питомца.

Cat класс наследуетStructureот Animal, Carnivore и Pet, чтобы также показатьПолиморфный бихевиоризмдомашнего питомца.

0
nabster

Если вы используете Java, это так просто:

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

Поправьте меня если я ошибаюсь.

0
Oliver Dixon