Herència (programació)

De Viquipèdia
Dreceres ràpides: navegació, cerca
Herència representada amb UML[1]. La classe derivada tindrà els atributs x i y, i els mètodes a() i b().

L’Herència és un dels conceptes fonamentals de la orientació a objectes i té gran importància en el desenvolupament de software. S’utilitza l’herència per crear classes noves a partir de les ja definides. Una classe nova pot ser una extensió o be una restricció de la classe original. A més d’aquest aspecte estructural, serveix també per documentar les semblances entre les classes, que és particularment important durant les primeres etapes del disseny de software, la nova classe està unida amb la classe original amb una relació "es-un" (engl. Is-A).

La classe que hereta es diu classe base (també super-classe o classe pare), la classe heretada s’anomena classe derivada (també sub-classe o classe fill), aquesta pren o hereta els atributs (variables) i comportament (mètodes) de la classe base (reutilitza codi). Aquest procés es denomina especialització, en sentit contrari en diríem generalització, termes limitats principalment a nivell de models. En llenguatge UML (Unified Modeling Language) una relació de herència es representa amb una fletxa triangular, apuntant a la classe base des de la classe derivada, els mètodes i atributs heretats no es repeteixen en la representació de la sub-classe.

Al 1967 el llenguatge de programació Simula introduïa per primera vegada el concepte de herència juntament amb altres conceptes de la programació orientada a objectes, com ara el polimorfisme.[2]

Les classes permeten especificar els tipus de les dades i les funcions que seran heretades. Alguns llenguatges de programació separen aquests aspectes encara que sigui parcialment, i distingeixen entre classe i interfície (engl. Interface).

Exemple d'herència[modifica | modifica el codi]

Exemple d'aplicació de l'herència ambUML.

El següent exemple representa una possible aplicació de l’herència, en aquest cas es tracta d’un sistema de lloguer de cotxes.

La classe base conté els atributs bàsics d’un vehicle qualsevol un identificador, el seu pes i el color, a més d’un mètode per comprovar la disponibilitat. Dintre del sistema distingirem entre vehicles amb motor o bicicletes, les especialitzacions heretaran els atributs i mètodes comuns, i n’afegiran els propis.

Cada objecte de la classe VehicleAmbMotor tindrà com atributs a part de l’identificador, pes i color, el quilometratge i la velocitat màxima del vehicle, i un mètode per comprovar la validesa del permís de conduir. Dins la classe Bicicleta l’unica informació addicional que podem necessitar en aquest cas és el tipus (muntanya, carretera, etc).

De la classe VehicleAmbMotor derivaran tres classes: Moto, Cotxe i Camió. La classe Cotxe afegeix informació sobre el nombre de places i la classe Camió sobre la carrega que pot portar. Podem veure que totes tres classes hauran de sobreescriure el mètode comprovarPermis(x) ja que es necessiten permisos de conduir diferents per portar un vehicle o un altre.


Exemple d'implementació de l'herència[modifica | modifica el codi]

L’ implantació es heretada de la classe base i implícitament també la seva interfície. La classe derivada assumeix el control dels atributs i funcions de la classe base, si es necessari afegeix atributs o funcions depenent si són rellevants o no per aquesta especialització.

L’exemple següent està escrit amb llenguatge Java, descriu la derivació d’un quadrat com una especialització del rectangle.

La classe rectangle té com atributs l’amplada i la longitud, que es passen com a paràmetres en el constructor. A més es defineixen mètodes per al càlcul del perímetre i la diagonal del rectangle (a més dels mètodes consultors).

L'especialització de quadrat, estén la funcionalitat de rectangle. El constructor de quadrat accepta només un paràmetre, la longitud del costat, dintre crida al constructor de la super-classe passant-li com a amplada i longitud el mateix valor, i per últim sobreescriu el comportament del mètode getDiagonal(), d’aquesta manera quan l’executem sobre un objecte de tipus quadrat s’executarà aquest codi i no el de la super-classe.


public class rectangle
{
    private double longitud;
    private double amplada;
 
    public rectangle(double longitud, double amplada)
    {
        this.amplada = amplada;
        this.longitud = longitud;
    }
 
    public double getLongitud() { return longitud; }
    public double getAmplada() { return amplada; }
 
    public double getPerimetre()
    {
        return 2 * longitud + 2 * amplada;
    }
 
    public double getDiagonal()
    {
        return Math.sqrt(longitud * longitud + amplada * amplada);
    }
}
public class quadrat extends rectangle
{
    // cácul de l'arrel quadrada
    static final double arrel2 = Math.sqrt(2);
 
    public quadrat(int longitud)
    {
        // Crida al constructor de la classe pare
        super(longitud, longitud);
    }
 
    @Override
    public double getDiagonal()
    {
        return arrel2 * getlongitud();
    }
}

Usos de l'herència [3][modifica | modifica el codi]

Herència d'implementació: s'utilitza com a reutilització de codi, una classe pot heretar comportament de la classe base, per tant el codi no s'ha de tornar a escriure.

Herència d'interfície: s'utilitza com a reutilització de conceptes, ens trobem quan la classe derivada sobreescriu el comportament definit per la classe base. Tot i que aquest codi no es comparteix entre les dues classes, comparteixen el prototip del mètode (comparteixen el concepte).

Tipus d'herència[modifica | modifica el codi]

Herència simple[modifica | modifica el codi]

La classe derivada hereta d'una única classe base.

Herència multiple[modifica | modifica el codi]

La classe derivada pot heretar de més d’una classe base parlem, no està permesa a tots els llenguatges de programació, en alguns només de manera limitada.


Vegeu també[modifica | modifica el codi]

Referències[modifica | modifica el codi]

  1. «Tutorial UML» (en castellà).
  2. Ole-Johan Dahl, Kristen Nygaard: Class and Subclass Declarations. In: J. N. Buxton (Hrsg.): Simulation Programming Languages. Proceedings of the IFIP working conference on simulation programming languages, Oslo, Mai 1967 North-Holland, Amsterdam, 1968, Seite 158–174 (online; PDF; 693 kB)
  3. «POO Herència».