Concetti OOPs per principianti: spiegazione del polimorfismo

Pubblicato: 2021-12-10

In linguaggi di alto livello come Python e Java, la programmazione OOP o orientata agli oggetti si riferisce all'organizzazione della progettazione del software attorno a dati e oggetti piuttosto che a logica e funzioni. Un oggetto è definito come un campo dati con attributi e comportamenti univoci. In altre parole, OOP si concentra sugli oggetti piuttosto che sulla logica. Un tale modello di programmazione è ideale per programmi grandi e complessi che richiedono aggiornamenti e manutenzione attivi. Inoltre, porta in tavola i vantaggi aggiuntivi di scalabilità, efficienza e riutilizzabilità del codice.

L'OOP ha quattro elementi costitutivi fondamentali: polimorfismo, incapsulamento, astrazione ed ereditarietà. Poiché lo scopo del nostro articolo è limitato al polimorfismo negli OOP, discuteremo in dettaglio il polimorfismo, inclusi esempi di polimorfismo in Java e polimorfismo in Python.

Impara i corsi di software online dalle migliori università del mondo. Guadagna programmi Executive PG, programmi di certificazione avanzati o programmi di master per accelerare la tua carriera.

Sommario

Definizione di polimorfismo

La definizione più semplice di polimorfismo sarebbe che polimorfismo significa esistere in varie forme. Ha le sue radici in due termini greci: "poly", che significa "numeroso" e "morph", che si traduce in "forme".

Per comprendere meglio il concetto, facciamo prima un semplice esempio. Prendi l'istanza del comportamento del cursore, lo stesso cursore che vedi muoversi sullo schermo ogni volta che usi un mouse o un trackpad. A seconda delle azioni dell'utente o della modalità del programma, il cursore può assumere forme diverse, come una freccia, una croce, una linea o un dito indice.

Il polimorfismo è una delle caratteristiche più significative dell'OOP. In Java e Python, variabili, oggetti e funzioni possono esistere in molte forme. Nel polimorfismo, una sottoclasse o un metodo definisce i suoi attributi e comportamenti pur mantenendo alcune delle funzionalità della sua classe madre. Questo ci porta all'ereditarietà, che consente di creare gerarchie di classi in cui una classe base fornisce i suoi attributi e il suo comportamento a una classe derivata. Successivamente, le funzionalità della classe derivata possono essere liberamente modificate o estese secondo necessità. A tal fine, il polimorfismo garantisce che venga eseguito il metodo corretto in base al tipo dell'oggetto chiamante.

Per metterlo in prospettiva, supponiamo di avere una classe che mostra la data e l'ora. Ora crei un metodo che eredita la classe e visualizza il messaggio "Hello!" insieme alla data e all'ora.

Esempio di polimorfismo in Java

Considera la superclasse "Shapes" che ha un metodo "area()". Le sottoclassi in "Forma" possono essere "Rettangolo", "Cerchio", "Triangolo", ecc. E ogni sottoclasse ha il suo metodo per calcolare l'area. Applicando i concetti di ereditarietà e polimorfismo, le sottoclassi utilizzano il metodo “area()” per trovare la formula per calcolare l'area della rispettiva forma.

classe Forme {

area vuota pubblica() {

System.out.println(“La formula per l'area di “);

}

}

classe Triangolo estende Forme {

area vuota pubblica() {

System.out.println("Il triangolo è 1/2 * base * altezza");

}

}

classe Cerchio estende Forme {

area vuota pubblica() {

System.out.println("Il cerchio è 3,14 * raggio * raggio ");

}

}

classe principale {

public static void main(String[] args) {

Shapes myShape = new Shapes(); // Crea un oggetto Shapes

Forme myTriangle = new Triangle(); // Crea un oggetto Triangolo

Forme myCircle = new Circle(); // Crea un oggetto Cerchio

myShape.area();

mioTriangolo.area();

myShape.area();

myCerchio.area();

}

}

L'output del codice di programma sopra sarà il seguente:

La formula per l'area del triangolo è 1/2 * base * altezza

La formula per l'area del Cerchio è 3,14 * raggio * raggio

Tipi di polimorfismo negli OOP

Il polimorfismo negli OOP è di due tipi: statico (polimorfismo in fase di compilazione) e dinamico (polimorfismo in fase di esecuzione).

1. Polimorfismo statico

In Java, l'overloading del metodo è il tipo più comune di polimorfismo statico. Può creare diversi metodi con lo stesso nome all'interno della stessa classe ma con parametri diversi. I set di parametri devono differire per almeno uno dei tre criteri seguenti:

  • I metodi devono avere un numero diverso di parametri.
  • I tipi di parametro devono essere diversi. Ad esempio, se un metodo accetta un Long, l'altro accetta un String.
  • I metodi dovrebbero accettare i parametri in ordini diversi. Ad esempio, se il metodo 1 accetta un Long e uno String, il metodo due deve accettare un String e quindi un Long.

Nell'overloading del metodo, durante la chiamata del metodo, il compilatore sceglie quale metodo chiamare in base ai parametri passati durante la chiamata. Ciò avviene in fase di compilazione e, quindi, questo tipo di polimorfismo viene anche definito polimorfismo in fase di compilazione.

Di seguito è riportato un esempio di codice Java per mostrare il polimorfismo in fase di compilazione. In questo esempio, il metodo add() è sovraccaricato con due diversi tipi di parametri.

pacchetto staticPolymorphism;

Aggiunta di classe pubblica

{

somma nulla(int x, int y)

{

int c = x+y;

System.out.println(“ Somma di due numeri :” +c); }

void sum(int x, int y, int z)

{

int c = x+y+z;

System.out.println(“ Somma di tre numeri :” +c); }

public static void main(String[] args)

{

Addition obj = new Addition();

ogg.sum ( 45,34);

ogg.sum(60, 32, 11);

}

}

L'output del programma di cui sopra sarà:

Aggiunta di due numeri:79

Aggiunta di tre numeri: 103

2. Polimorfismo dinamico

Il polimorfismo dinamico o di runtime si ottiene attraverso l'override del metodo. Qui, i metodi sono in forme diverse in classi diverse (override del metodo) e invece della fase di compilazione, la chiamata a un metodo sottoposto a override viene risolta in fase di esecuzione. Ora, dopo aver assegnato un oggetto a un riferimento di classe e aver chiamato un metodo, il metodo nella classe dell'oggetto viene eseguito. Poiché l'oggetto viene creato in fase di esecuzione, la forma del metodo (nell'oggetto) che deve essere eseguito viene decisa solo in fase di esecuzione.

Di seguito è riportato un esempio di codice Java per mostrare il polimorfismo di runtime . Nell'esempio, c'è una superclasse "Animale" e tre sottoclassi, "canguro", "tigre" e "pesce". Le sottoclassi estendono la superclasse e sovrascrivono il suo metodo "move()". Il metodo "move()" viene chiamato dalla variabile di riferimento della classe genitore "Animal".

classe Animale{

mossa vuota(){

System.out.println("Gli animali si muovono");

}

}

canguro di classe estende Animale{

mossa vuota(){

System.out.println("I canguri saltano");

}

}

classe tigre estende Animale{

mossa vuota(){

System.out.println("La tigre cammina");

}

}

pesce di classe si estende Animale{

mossa vuota(){

System.out.println("Nuota di pesce");

}

}

classe principale{

public static void main(String args[]){

Animale A = nuovo Animale();

Animale k = nuovo canguro(); //trasmissione

Animale t = nuova tigre(); //trasmissione

Animale f = nuovo pesce(); //trasmissione

Una mossa();

k.sposta();

t.sposta();

f.sposta();

}

}

L'output del programma di cui sopra sarà:

Gli animali si muovono

I canguri saltano

Le tigri camminano

I pesci nuotano

Polimorfismo in Python

Il polimorfismo in Python è di tre tipi: polimorfismo degli operatori, polimorfismo delle funzioni e polimorfismo delle classi. Python consente anche l'override del metodo ma non l'override del metodo.

1. Polimorfismo dell'operatore

In Python, l'operatore '+' ha un doppio utilizzo. Viene utilizzato per le operazioni di addizione aritmetica nel caso di tipi di dati interi e per le stringhe l'operatore '+' esegue le concatenazioni.

Di seguito è riportato un esempio di codice Python in cui l'operatore '+' esegue l'addizione su tipi di dati interi:

num1 = 4

num2 = 5

stampa(num1+num2)

L'output del codice del programma sopra è '9.'

Di seguito è riportato un esempio di codice Python in cui l'operatore '+' esegue la concatenazione su tipi di dati stringa:

str1 = “Buono”

str2 = “Sera”

print(str1+” “+str2)

L'output del programma di cui sopra sarà "Buonasera".

2. Polimorfismo funzionale

La funzione 'len()' in Python è compatibile con diversi tipi di dati come list, string, tuple, dictionary e set, ma restituisce informazioni specifiche per ogni tipo di dati. Ecco un esempio:

print(len("Programmatore"))

print(len([“Python”, “Java”, “C”]))

print(len({"Nome": "Kathy", "Indirizzo": "Texas"}))

Il programma di cui sopra avrà il seguente output:

9

3

2

3. Polimorfismo di classe

Estendendo il concetto di polimorfismo, Python consente a più classi di avere metodi con lo stesso nome. Di seguito è riportato un esempio per mostrare il polimorfismo nei metodi di classe in Python. Nell'esempio, ci sono due classi, "Gatto" e "Cane". Hanno una struttura simile e hanno gli stessi nomi di metodo "make_sound()" e "info()".

classe Gatto:

def __init__(sé, nome, età):

self.name = nome

auto.età = età

def info(auto):

print(f"Sono un gatto. Mi chiamo {self.name}. Ho {self.age} anni.")

def make_sound(self):

print("Miao")

classe Cane:

def __init__(sé, nome, età):

self.name = nome

auto.età = età

def info(auto):

print(f"Sono un cane. Mi chiamo {self.name}. Ho {self.age} anni.")

def make_sound(self):

print("Corteccia")

cat1 = Gatto("Minnie", 3)

cane1 = Cane(“Tom”, 6)

per animale in (cat1, dog1):

animal.make_sound()

animal.info()

animal.make_sound()

L'output sarà il seguente:

Miao

Sono un gatto. Mi chiamo Minni. Ho 3 anni.

Miao

Abbaiare

Io sono un cane. Il mio nome è Tom. Ho 6 anni.

Abbaiare

4. Sovrascrittura del metodo

Python consente anche alle classi figlie di ereditare attributi e metodi dalla classe genitore. Alcuni metodi e attributi possono essere ridefiniti per adattarsi alla classe figlia (override del metodo). Il polimorfismo consente quindi l'accesso ai metodi e agli attributi sottoposti a override con lo stesso nome della classe padre.

Di seguito è riportato un esempio di codice Python per illustrare l'override del metodo:

da math import pi

Classe Forma:

def __init__(self, nome):

self.name = nome

def area (auto):

passaggio

def fatto (auto):

ritorna “Sono una figura chiusa”.

def __str__(self):

restituire il proprio nome

classe Quadrato (Forma):

def __init__(self, lunghezza):

super().__init__("Quadrato")

self.length = lunghezza

def area (auto):

ritorno self.length**2

def fatto (auto):

restituisce "Ogni angolo in un quadrato è uguale a 90 gradi."

classe Cerchio (Forma):

def __init__(self, raggio):

super().__init__("Cerchio")

self.radius = raggio

def area (auto):

restituisce pi*self.radius**2

a = quadrato(4)

b = Cerchio(7)

stampa(b)

print(b.fact())

print(a.fatto())

print(b.area())

Il programma di cui sopra avrà il seguente output:

Cerchio

Sono una figura chiusa.

Ogni angolo in un quadrato è uguale a 90 gradi.

153.93804002589985

Ulteriori informazioni sull'override del metodo.

Vantaggi del polimorfismo negli OOP

Il polimorfismo negli OOP ha tre vantaggi significativi. Sono i seguenti:

  • Il polimorfismo consente la riutilizzabilità del codice. Quindi, una volta che le classi sono state scritte, testate e implementate, puoi riutilizzarle ancora e ancora. Inoltre, il codice può essere modificato senza influire sul codice originale. Tutto ciò consente di risparmiare tempo significativo per il programmatore.
  • Nel polimorfismo, più valori di dati possono essere archiviati in una singola variabile. Inoltre, il valore di una variabile ereditato da una superclasse in una sottoclasse può essere modificato senza modificare il valore della variabile nella superclasse o in qualsiasi sottoclasse.
  • Infine, il polimorfismo funziona con un minor numero di righe di codice, il che, a sua volta, rende il debug più semplice per il programmatore.

Via avanti

upGrad, in collaborazione con la prestigiosa Liverpool John Moores University, offre un rigoroso programma online di Master of Science in Data Science per professionisti che aspirano a fare carriera nella scienza dei dati. Il corso si conclude con un Master presso LJMU e una certificazione Executive PG Program di IIIT Bangalore.

Punti salienti del programma:

  • Oltre 500 ore di contenuti, oltre 60 casi di studio e progetti, oltre 20 sessioni dal vivo
  • Copertura completa di oltre 14 strumenti e software come Python, AWS, MySQL e altro ancora
  • Sessioni di coaching con esperti del settore
  • Apprendimento tra pari e networking di settore
  • Assistenza professionale a 360 gradi

Una delle migliori piattaforme EdTech superiori oggi, upGrad continua a ispirare e preparare gli studenti attraverso una combinazione di tecnologia all'avanguardia, l'ultima pedagogia, partnership industriali e una facoltà di livello mondiale.

Impara i corsi di scienza dei dati online dalle migliori università del mondo. Guadagna programmi Executive PG, programmi di certificazione avanzati o programmi di master per accelerare la tua carriera.

Perché il polimorfismo viene utilizzato negli OOP?

In OOP, il polimorfismo è il metodo che esegue diverse attività in base alla classe dell'oggetto che lo chiama. Pertanto, un messaggio viene inviato a oggetti di più classi e ogni oggetto risponde in base alle proprietà della classe.

Che cos'è il sovraccarico del metodo in Java?

In Java, due o più metodi con lo stesso nome possono differire nei parametri (diversi tipi di parametri, diversi numeri di parametri o entrambi). Tali metodi sono chiamati metodi di overload e la funzionalità è denominata overloading del metodo.

Qual è la differenza tra sovraccarico e override?

Quando due o più metodi nella stessa classe hanno parametri diversi ma lo stesso nome, si parla di overloading. D'altra parte, l'override è quando la superclasse e la classe figlia hanno la stessa firma del metodo (nome e parametri).