Polymorfism (objektorienterad programmering)

För andra betydelser, se Polymorfism.

Polymorfism innebär inom objektorienterad programmering att flera olika subklasser under en superklass kan hanteras som om de vore instanser av superklassen.[1] Det innebär att klasser med olika behov vad gäller implementering av en viss metod, ändå kan anropas på samma sätt. Den verkställande programkoden finns i respektive subklass, medan det gemensamma gränssnittet definieras i superklassen.

Programexempel

Antag att klasserna Turtle och Hare båda är subklasser till klassen Animal. I sådana fall kan metoder som är gemensamma för haren och sköldpaddan samlas i klassen Animal, till exempel en metod som skriver ut den aktuella hastigheten med vilken djuret rör sig. Det finns också egenskaper hos en sköldpadda och en hare som är gemensamma, men som inte kan implementeras på samma sätt i de båda klasserna, till exempel springer en hare mycket fortare än en sköldpadda. Sådana metoder lämpar sig mycket väl för att implementeras polymorfiskt.

Följande är ett exempel på en arvshierarki i programmeringsspråket C++ där metoderna run() och walk() används polymorfiskt. Detta program ger följande utskrift:

Djuret Sköldpadda har hastigheten 1
Djuret Sköldpadda har hastigheten 2
Djuret Sköldpadda har hastigheten 1
Djuret Hare har hastigheten 1
Djuret Hare har hastigheten 11
Djuret Hare har hastigheten 1

Nedan definieras de tre klassernas gemensamma gränssnitt i superklassen, och metoderna implementeras. I huvudprogrammet (där klasserna skapas och anropas) skapas en array som håller pekare till ett objekt av typen Hare och ett objekt av typen Turtle. Sedan skapas en for-loop som itererar över arrayen och anropar metoden print_current_speed() för att sedan anropa de polymorfa metoderna run() och walk() som höjer respektive sänker djurets hastighet. Däremellan anropas print_current_speed() för att kontrollera att hastigheten verkligen förändras.

#include <iostream>
#include <string>
class Animal //Den gemensamma superklassen
{
	protected: //Attribut som bara har synlighet från subklasser 
		std::string name; //Djurets namn
		int speed; //Djurets hastighet
	public: //Metoder med allmän synlighet
		Animal(int s, std::string n); //Konstruktor
		void print_current_speed(); //Metod för att skriva ut hastigheten
		void virtual run() = 0; //Två virtuella metoder som ändrar djurets hastighet
		void virtual walk() = 0;
};
Animal::Animal(int s, std::string n) //Implementering av konstruktorn för klassen Animal
{
	speed = s;
	name = n;	
}
//Nedan är implementeringen av hastighetsutskriften
void Animal::print_current_speed() {std::cout << "Djuret " << name << " har hastigheten " << speed << std::endl;}

class Turtle: public Animal //Subklassen Turtle
{
	public: //Metoder med allmän synlighet
		Turtle();
		void run();
		void walk();
};

Turtle::Turtle(): Animal(1, "Sköldpadda"){} //Konstruktorn för Turtle anropar här bara superklassens konstruktor
void Turtle::run() {speed++;} //Sköldpaddans springmetod ökar hastigheten med ett
void Turtle::walk() {speed--;} //Sköldpaddans gåmetod minskar hastigheten med ett

class Hare: public Animal //Subklassen Hare
{
	public: //Metoder med allmän synlighet
		Hare();
		void run();
		void walk();
};
Hare::Hare(): Animal(1, "Hare"){} //Konstruktorn för Hare anropar också bara superklassens konstruktor
void Hare::run() {speed = speed + 10;} //Harens springmetod ökar dock hastigheten med 10
void Hare::walk() {speed = speed - 10;} //och gåmetoden sänker den följaktligen också med 10

int main(int argc, char** argv) //Huvudprogrammet
{
	Animal *animal_arr[2]; //Deklarera en array med pekare till Animalobjekt
	animal_arr[0] = new Turtle(); //Här läggs en pekare till ett Turtleobjekt in i arrayen
	animal_arr[1] = new Hare(); //Här läggs en pekare till ett Hareobjekt in i arrayen
	
	for(int i = 0; i < 2; i++) //Här skapas en for-loop som går igenom arrayen
	{
		animal_arr[i]->print_current_speed(); //Skriv ut hastigheten
		animal_arr[i]->run(); //Anropa springfunktionen för det aktuella objektet
		animal_arr[i]->print_current_speed(); //Skriv ut hastigheten igen
		animal_arr[i]->walk(); //Anropa gåfunktionen för det aktuella objektet
		animal_arr[i]->print_current_speed(); //Skriv återigen ut hastigheten
	}
	
	return 0; //Programmet avslutas
}

Referenser

Fotnoter

  1. ^ Deitel 2014, s 442 ff

Litteratur

  • Deitel, Paul J.; Deitel Harvey M. (2014) (på engelska). Visual C# 2012: how to program (5. ed., Internat. ed.). Boston: Pearson. Libris 14932043. ISBN 9780273793304 

Se även