Klass (programmering)

Klass är i objektorienterad programmering ett avsnitt programkod som samlar en mängd relaterade attribut och funktioner, även kallat metoder. Det är ett viktigt kännetecken för en klass att dess inre struktur inte är tillgänglig utanför klassen, utan den kan enbart manipuleras genom ett specificerat gränssnitt. Fenomenet att en klass privata delar ej är tillgängliga utanför kallas inkapsling (eng. encapsulation). En klass kan sägas vara en användardefinierad datatyp, som alltså kompletterar de fördefinierade datatyperna, i C++ till exempel int och char. För att de klasserna skall likna just användardefinierade datatyper använder man i vissa språk överlagring av operatorer för klasser.

Arvshierarkier

Objektorienterade programmeringsspråk tillåter klasser att ärva egenskaper från andra klasser i ett eller flera led. En klass som en annan klass ärver egenskaper ifrån kallas för superklass (överklass, basklass) medan den klass som ärver egenskaperna benämns subklass (underklass, härledd klass). [källa behövs]

Exempel på klass i C++

#include <string>
class example
{
    public:
        example(int no, string s); //Konstruktor
        void add(int no); //Metod för att addera värden med variabeln "value"
        void subtract(int no); //Metod för att subtrahera från variabeln "value"
        void change_name(string s); //Metod för att ändra innehållet i strängvariabeln "name"
 
    protected:
        int value; //En heltalsvariabel 
        std::string name; //En strängvariabel
 
};
 
example::example(int no, string s)
{
    value = no; //Initering av de båda variablerna
    name = s;
}
 
void example::add(int no)
{
    value += no; //"no" adderas till "value"
}
 
void example::subtract(int no)
{
    value -= no; //"no" subtraheras från "value"
}
 
void example::change_name(string s)
{
    name = s; //name ändras till s
}

int main()
{
    example test(10, "test"); //Objektet "test" initieras, value = 10, name = test
    test.add(10); //"value" ökar med 10
    test.subtract(5); //"value" minskar med 5, innehåller just nu 15
    test.change_name("example"); //Variabeln "name" ändras från "test" till "example"
    return 0;
}

Koden ovan definierar en klass som består av en variabel av typen int och en variabel av typen string (som inte är en primitiv datatyp, utan en egen klass). Dessutom anges metoder för att manipulera dessa värden, men inte för att hämta information från klassen. Ingen utskrift kan därför heller ske i huvudprogrammet, eftersom datan har gömts för alla utom arvingar till klassen (se vidare nedan).

Exempel på en subklass i C++

Exempleklassen ovan saknar vissa metoder som kan vara bra att ha och dessutom kanske man vill kunna lagra ytterligare värden förutom ett heltal och en textsträng. Ett alternativ är då att skapa en subklass till klassen exempel (i stället för att skriva om koden till klassen example). Det ser ut så här:

class betterexample : public example
{
    //En klass är default private, alltså måste följande rad inte skrivas.
    //private:
        double anothervalue; //Ett attribut av typen double

    public:
        betterexample(int no, string s, double an); //Konstruktor
        int getValue(); //Metod för att komma åt "value", som finns i superklassen
        string getName(); //Metod för att hämta "name", som också finns i superklassen
        double getAnothervalue(); //Metod för att hämta "anothervalue", som bara finns i subklassen
};
 
betterexample::betterexample(int no, string s, double an): example(no, s) //Anrop till superklassens konstruktor
{
    anothervalue = an; //Initiering av den egna variabeln
}
 
int betterexample::getValue() 
{
    return value; //Hämtar "value" som definierats i superklassen
}
 
string betterexample::getName()
{
    return name; //Hämtar "name" som definierats i superklassen
}
 
double betterexample::getAnothervalue()
{
    return anothervalue; //Hämtar "anothervalue" som definierats på plats i subklassen
}

Här ärver klassen "betterexample" alla attribut och metoder från klassen example. Därtill definieras ett eget attribut, ett flyttal kallat "anothervalue" liksom metoder som kan användas för att hämta alla värden som lagras i klassen. Om man lägger till koden för "betterexample" till den som redan finns för "example" skulle man kunna definiera ett huvudprogram som ser ut så här:

int main()
{

    betterexample nytt_test(10, "nytt test", 20.5); //Skapar ett objekt av typen "betterexample"
    nytt_test.add(20); //adderar 20 till heltalet "value"
    cout << nytt_test.getValue() << endl; //skriver ut värdet av "value"
    cout << nytt_test.getAnothervalue() << endl; //Skriver ut värdet av "anothervalue"
    cout << nytt_test.getName() << endl; //Skriver ut värdet av "name"

    return 0;
}

Utskriften från detta program blir:

30
20.5
nytt test

Abstrakt klass

I objektorienterad programmering kan abstrakta klasser definieras. Detta är klasser som inte kan instansieras, vilket innebär att det inte går att skapa objekt av klassen. I stället får man definiera en klass som ärver den abstrakta, och på så sätt skapa objekt.

Ett exempel kan vara klassen Däggdjur. I den kan definieras egenskaper och metoder som är gemensamma för alla däggdjur, men ett antal egenskaper som storlek, dräktighetstid etc kan inte definieras utan att veta vilket djur det rör sig om. Typiskt anger Däggdjur att det har en längd, men kan inte svara på hur stor den är.

Genom att definiera Människa och Delfin som klasser som ärver Däggdjur, och tillföra specifika egenskaper och metoder för sådant som skiljer, kan man både få god utvecklingsekonomi och en beskrivande struktur.

Abstrakta klasser är också praktiska för användare. Ett program för en zoologisk trädgård har troligen behov av att hålla kollektioner av objekt som har klassen Däggdjur eller rentav Djur, och nöjer sig med att respektive objekt själv vet vilken klass det egentligen implementerar.

Interface kan ses som ett specialfall av abstrakta klasser. Dessa innehåller enbart definitioner av metoder, och ingen implementering alls.