Qual è la principale differenza tra ereditarietà e polimorfismo?

Mi è stata presentata questa domanda in un esame di fine libro aperto e oggi mi sono ritrovato perso. Stavo leggendo Head first Java e entrambe le definizioni sembravano essere esattamente le stesse. Mi stavo chiedendo quale fosse la differenza principale per il mio personale pensiero. So che ci sono un certo numero di domande simili a questo ma, nessuno che ho visto che fornisca una risposta definitiva.

L’ereditarietà è quando una “class” deriva da una “class” esistente. Quindi se hai una class Person , allora hai una class Student che estende la Person , lo Student eredita tutte le cose che la Person ha. Ci sono alcuni dettagli sui modificatori di accesso che hai inserito nei campi / metodi in Persona, ma questa è l’idea di base. Ad esempio, se hai un campo privato su Person , lo Student non lo vedrà perché i suoi campi privati ​​e privati ​​non sono visibili alle sottoclassi.

Il polimorfismo riguarda il modo in cui il programma decide quali metodi utilizzare, a seconda del tipo di cosa che ha. Se hai una Person , che ha un metodo di read , e hai uno Student che estende la Person , che ha una propria implementazione di read , quale metodo viene chiamato è determinato per te dal runtime, a seconda che tu abbia una Person o uno Student . Diventa un po ‘complicato, ma se fai qualcosa del genere

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

viene chiamato il metodo di lettura su Student . Questo è il polimorfismo in azione. Puoi eseguire questo compito perché uno Student è una Person , ma il runtime è abbastanza intelligente da sapere che il tipo effettivo di p è Studente .

Si noti che i dettagli differiscono tra le lingue. Ad esempio, puoi fare l’ereditarietà in javascript, ma è completamente diverso dal modo in cui funziona in Java.

L’ereditarietà si riferisce all’utilizzo della struttura e del comportamento di una super class in una sottoclass.

Il polimorfismo si riferisce al cambiamento del comportamento di una super class nella sottoclass.

Polimorfismo : la capacità di trattare oggetti di tipi diversi in modo simile. Esempio: la giraffa e il coccodrillo sono entrambi animali e gli animali possono Move . Se hai un’istanza di un Animal , puoi chiamare Move senza sapere o preoccuparti di quale tipo di animale sia.

Ereditarietà : questo è un modo per ottenere contemporaneamente il polimorfismo e il riutilizzo del codice.

Altre forms di polimorfismo : ci sono altri modi per ottenere il polimorfismo, come le interfacce, che forniscono solo il polimorfismo ma nessun riutilizzo del codice (a volte il codice è molto diverso, come Move for a Snake sarebbe molto diverso da Move for a Dog, in in tal caso un’interfaccia sarebbe la scelta polimorfica migliore in questo caso.

In altri linguaggi dinamici è ansible ottenere il polimorfismo con Duck Typing, che non richiede nemmeno che le classi condividano la stessa class base o interfaccia, ma solo un metodo con lo stesso nome. O ancora più dinamico come Javascript, non hai nemmeno bisogno di classi, solo un object con lo stesso nome di metodo può essere usato polimorficamente.

La principale differenza è che il polimorfismo è un risultato specifico dell’ereditarietà. Il polimorfismo è il punto in cui il metodo da invocare viene determinato al momento dell’esecuzione in base al tipo dell’object. Questa è una situazione che si verifica quando una class eredita da un’altra e sovrascrive un particolare metodo. Tuttavia, in un normale albero di ereditarietà, non è necessario sovrascrivere alcun metodo e quindi non tutte le chiamate ai metodi devono essere polimorfiche. Ha senso? È un problema simile a tutti i veicoli Ford sono automobili, ma non tutte le automobili sono Ford (anche se non del tutto ….).

Inoltre, il polimorfismo riguarda l’invocazione del metodo, mentre l’ereditarietà descrive anche i membri dei dati, ecc.

In Java, i due sono strettamente correlati. Questo perché Java utilizza una tecnica per l’invocazione del metodo chiamata “invio dinamico”. Se ho

 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 

Quindi vediamo che B eredita lo spin da A. Tuttavia, quando proviamo a manipolare l’object come se fosse un tipo A, otteniamo comunque il comportamento di B per l’ draw . Il comportamento di draw è polimorfico.

In alcune lingue, il polimorfismo e l’ereditarietà non sono strettamente correlati. In C ++, ad esempio, le funzioni non dichiarate virtuali vengono ereditate, ma non verranno inviate dynamicmente, quindi non si otterrà quel comportamento polimorfico nemmeno quando si utilizza l’ereditarietà.

In javascript, ogni chiamata di funzione viene inviata dynamicmente e la digitazione è debole. Ciò significa che potresti avere un gruppo di oggetti non correlati, ognuno con il proprio draw , avere una funzione iterare su di essi e chiamare la funzione, e ognuno si comporterebbe bene. Avresti il ​​tuo disegno polimorfico senza bisogno di ereditarietà.

Polymorphism: Supponiamo che lavori per un’azienda che vende penne. Quindi fai una bella lezione chiamata “Penna” che gestisce tutto ciò che devi sapere su una penna. Scrivi tutti i tipi di classi per la fatturazione, la spedizione, la creazione di fatture, tutto utilizzando la class Pen. Arriva un capo del giorno e dice: “Ottima notizia! La società sta crescendo e ora vendiamo libri e CD!” Non è una grande notizia, perché ora devi cambiare ogni class che usa Pen per usare anche Book & CD. Ma se aveste originariamente creato un’interfaccia chiamata “SellableProduct”, e Pen ha implementato questa interfaccia. Quindi potresti aver scritto tutte le tue lezioni di spedizione, fatturazione, ecc. Per usare quell’interfaccia invece di Pen. Ora tutto ciò che dovresti fare è creare una nuova class chiamata Book & CompactDisc che implementa l’interfaccia SellableProduct. A causa del polimorfismo, tutte le altre classi potrebbero continuare a funzionare senza cambiamenti! Ha senso?

Quindi, significa usare l’ereditarietà che è uno dei modi per ottenere il polimorfismo.

Il polimorfismo può essere ansible in una class / interfaccia ma Eredità sempre tra 2 O più classi / interfacce. L’ereditarietà è sempre conforms alla relazione “è-a”, mentre non è sempre con il Polymorphism (che può essere conforms sia alla relazione “is-a” / “ha-a”.

L’ereditarietà è più una cosa statica (una class ne estende un’altra) mentre il polimorfismo è una cosa dynamic / di esecuzione (un object si comporta in base al suo tipo dinamico / runtime non al suo tipo statico / di dichiarazione).

Per esempio

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

-> Anche se il tipo statico / di dichiarazione di a è A, il tipo dinamico / runtime attuale è B e quindi a.foo () eseguirà foo come definito in B non in A.

Il polimorfismo è un approccio per esprimere un comportamento comune tra tipi di oggetti che hanno caratteristiche simili. Permette anche di creare variazioni di quei tratti da creare attraverso l’override. L’ereditarietà è un modo per ottenere il polimorfismo attraverso una gerarchia di oggetti in cui gli oggetti esprimono relazioni e comportamenti astratti. Tuttavia, non è l’unico modo per ottenere il polimorfismo. Prototipo è un altro modo per esprimere il polimorfismo che è diverso dall’ereditarietà. JavaScript è un esempio di un linguaggio che utilizza il prototipo. Immagino ci siano anche altri modi.

L’ereditarietà è un concetto correlato al riutilizzo del codice. Ad esempio, se ho una class genitrice, dico Animal e contiene determinati attributi e metodi (per questo esempio dice makeNoise() e sleep() ) e creo due classi figlio chiamate Dog e Cat . Poiché sia ​​i cani che i gatti vanno a dormire nello stesso modo (suppongo) non è necessario aggiungere più funzionalità al metodo sleep() nelle sottoclassi Dog e Cat fornite dalla class genitore Animal . Tuttavia, un Dog abbaia e un Cat miagola, quindi anche se la class degli Animal potrebbe avere un metodo per fare rumore, un cane e un gatto emettono rumori diversi l’uno rispetto all’altro e agli altri animali. Quindi, c’è bisogno di ridefinire quel comportamento per i loro tipi specifici. Quindi la definizione di polimorfismo. Spero che questo ti aiuti.

La documentazione Oracle citava esattamente la differenza.

ereditarietà: una class eredita campi e metodi da tutte le sue superclassi, sia dirette che indirette. Una sottoclass può sovrascrivere i metodi che eredita oppure può hide campi o metodi che eredita . (Nota che hide i campi è in genere una ctriggers pratica di programmazione.)

polimorfismo: il polimorfismo si riferisce a un principio in biologia in cui un organismo o una specie possono avere molte forms o stadi diversi. Questo principio può essere applicato anche alla programmazione orientata agli oggetti e ai linguaggi come il linguaggio Java. Sottoclassi di una class possono definire i propri comportamenti univoci e tuttavia condividere alcune delle stesse funzionalità della class genitore.

il polimorfismo non è applicabile per i campi.

Post correlati:

Polimorfismo vs Override vs Sovraccarico

L’ereditarietà è quando la class A eredita tutti i metodi / campi non statici protetti / pubblici da tutti i suoi genitori fino all’object.

Se usi JAVA è semplice come questo:

Il polimorfismo utilizza metodi ereditati, ma “Sovrascrivi” per fare qualcosa di diverso (o lo stesso se chiami super, quindi tecnicamente non sarebbe polimorfico).

Correggimi se sbaglio.

Lo scopo principale del polimorfismo : creare una variabile di riferimento in super-class e mantenere la sottoclass object => un object può eseguire più comportamenti .

Nell’ereditarietà , la sottoclass eredita le proprietà della super class .

l’ereditarietà è un tipo di polimorfismo, in effetti l’ereditarietà è il polimorfismo dinamico. Quindi, quando rimuovi l’ereditarietà non puoi più ignorare.

Il polimorfismo si ottiene con l’ ereditarietà in 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 class dei Hamster eredita la struttura da Animal , Herbivore e Pet per esibire il comportamentismo polimorfico di un animale domestico domestico.

Cat class Cat eredita la struttura da Animal , Carnivore e Pet per mostrare anche il comportamentismo Polimorfico di un animale domestico domestico.