Arv i Java: Ärv kod från andra klasser


Nyckelord: arv, inheritance, extends, klass, super, final

inheritance arv Java

I den här artikeln kommer vi lära oss om arv (engelska: inheritance) som är ett sätt att återanvända kod från redan existerande klasser. Arv är en av de viktigaste funktionerna inom objektorienterad programmering som gör att vi kan definiera en ny klass från en befintlig klass.

Vad är arv i Java?

Arv (engelska: inheritance) använder man i Java för att återanvända kod från andra klasser. Likt det vi tog upp för metoder gällande att det är vanligt att man vill återanvända sin kod flera gånger och strukturera den i flera delar, så vill man även kunna återanvända kod från klasser man redan har programmerat. Det man kan göra är att istället för att programmera liknande klasser flera gånger, kan man ärva kod från en annan klass.

Hur fungerar arv i Java?

Först och främst så brukar arv delas in i två huvudkategorier:

  1. Subklass (child): en klass som ärver från en annan klass kallas för en subklass, eller för ett barn/child.
  2. Superklass (parent): den klass som arvet sker från kallas för superklass, eller förälder.

Det som sker vid ett arv är att subklassen får samma uppsättning av instansvariabler och metoder som superklassen, men det är även möjligt att lägga till nya metoder och klassvariabler om så önskas. Med andra ord, vid ett arv så får subklassen samma instansvariabler och metoder, men det går självklart även att lägga till fler om vi så vill.

Kortfattat om arv i Java:

  • Ett sätt att återanvända kod från en annan klass.
  • En klass som ärver kod kallas för subklass och den klass som blir ärvd från kallas superklass. Kan även kallas för ett parent-child förhållande
  • En subklass får samma uppsättning av instansvariabler som superklassen.
  • I subklassen kan man definiera nya attribut och egenskaper.

Idén med arv är enkel men kraftfull: När du vill skapa en ny klass och det redan finns en klass som innehåller en del av koden du vill kan du härleda din nya klass från den befintliga klassen. Genom att göra detta kan du återanvända fälten och metoderna för den befintliga klassen utan att behöva skriva (och felsöka!) dem själv.

Oracle

Hur skapar man arv i Java?

En subklass skapas på liknande sätt som när vi definierade en klass, med skillnaden att vi använder nyckelordet extends följt av den superklass som vi vill att klassen ska ärva från. Det nyckelordet extends anger är att du skapar en ny klass som härrör från en befintlig klass.

Syntax: Arv i Java

class SubClassNamn extends SuperClassNamn 
{  
   // Kod som tillhör klassen  
}  

Nyckelordet super

Nyckelordet super används för att kalla på konstruktorn i superklassen. När du skapar en subklass så skapas implicit förekomsten av en överordnad superklass. Helt enkelt, det är med hjälp av nyckelordet super som vi kan referera till variabler i superklassen från subklassen. 

Exempelvis

class Furniture {  
   String color="white";  
}

// Subklassen Chair som ärver från superklassen Furniture  
class Chair extends Furniture{  
   String color="brown";  

   // En metod som skriver ut färgen i Chair och Furniture
   void printColor(){  

      // Skriv ut färgen av Chair klassen  
      System.out.println(color); 

      //Skriv ut färgen av Furniture klassen  
      System.out.println(super.color); 
   }  
}  

class TestSuperExample {  
   public static void main(String args[]){  
      Chair c = new Chair();
      c.printColor();  
   }
}  

Kommer att resultera i

white
brown 

Nyckelordet final

Om du inte vill att andra klasser ska ärva från en klass så använder man nyckelordet final.

Exempelvis, om vi skriver:

final class Animal {
   // Kod som tillhör klassen Animal
}

class Cat extends Animal {
   // Kod som tillhör klassen Cat
}

och sedan exekverar koden så kommer vi få felmeddelandet: java: cannot inherit from final Animal

Olika typer av Arv i Java

Det finns tre olika typer av arv i Java som vi kan utföra. Notera hur vi använder ordet extends för att en klass ska ärva kod.

Enkelt Arv i Java

Ett enkelt, eller även kallat single, arv i Java betyder att vi har en subklass som ärver av en superklass.

class A { 
   // Kod som tillhör superklassen
}

class B extends A {
   // Kod som tillhör subklassen
}

Om vi illustrerar ett enkelt arv med en figur

Arv Java

Figur 1: Enkelt arv i Java

Arv på flera nivåer

Ett arv på flera nivåer, även referat till som multilevel arv, betyder att vi har en subklass som ärver av en annan subklass.

class A { 
   // Kod som tillhör superklassen
}

class B extends A {
   // Kod som tillhör subklassen
}

class C extends B { 
   // Kod som tillhör subklassen
}

På liknande sätt som innan, låt oss illustrera ett arv på flera nivåer som

Multilevel Arv Java

Figur 2: Arv på flera nivåer

Hierarkisk arv i Java

Slutligen har vi vad som kallas för hierarkiskt arv som innebär att vi har två subklasser som ärver från samma superklass.

class A { 
   // Kod som tillhör superklassen
}

class B extends A {
   // Kod som tillhör subklassen
}

class C extends A { 
   // Kod som tillhör subklassen
}

Självklart ska vi illustrera det sambandet också.

Hierarkisk arv Java

Figur 3: Hierarkiskt arv i Java

Arv som inte stöds i Java

Java stödjer inte så kallade multipla, eller flertalet, arv. Ett multipelt arv är då en klass ärver kod från flera klasser, till exempel, att klass C ärver kod från klass A och klass B samtidigt.

Om vi illustrerar hur ett multiplet arv kan se ut

Arv Inheritance Java

Figur 4: Multipla arv som ej stöds i Java

Det finns en lösning på de situationer då man vill använda multipla arv genom att implementera ett eller flera interface, som vi kommer gå igenom på nästa sida.

Exempel: Hur man skapar arv i Java

Låt oss ta två exempel, ett kortare exempel och sedan ska vi fortsätta på det exempel vi inledde på föregående sidor.

Exempel 1: Skapa Arv i Java

class Company{
    int salary = 40000;
    String companyPhone = "iPhone 11";
}

// Klassen ProjectLeader ärver från superklassen Company
class ProjectLeader extends Company{
    int projectSalary = 10000;

    public static void main(String args[]){
        ProjectLeader tl=new ProjectLeader ();
        System.out.println("Grundlönen är: "+ tl.salary);
        System.out.println("Bonus för teamledare: " + tl. projectSalary);
        System.out.println("Företagsmobilen är: " + tl. companyPhone);

    }
}

Avslutningsvis, resultatet om vi exekverar programmet blir

Grundlönen är: 40000
Bonus för teamledare: 10000
Projektledaren har mobiltelefon: iPhone 11

Exempel 2: Klassen Dog för en hund

Vi fortsätter nu på exemplet för klassen Dog som vi inledde i föregående artiklar. I föregående avsnitt skapade vi klassen Dog. Vi skapar nu subklassen SubDog som ska ärva från klassen Dog.

//Skapar klassen "Dog". Praxis är att klassnamn har stor bokstav
class Dog {

    //Definierar klassvariablerna (egenskaperna) för klassen hund
    String name;
    int age;
    String breed;
    String color;

    //Definiera konstruktorn
    Dog(String name, int age, String breed, String color){
        this.name = name;
        this.age = age;
        this.breed = breed;
        this.color = color;
    }

    //Definierar metoderna för klassen hund
    void bark(){
        System.out.println(this.name + " skäller");
    }

    void eat(){
        System.out.println(this.name + " äter");
    }

    void sleep(){
        System.out.println(this.name + ": zZZzzZzzZ");
    }

    public static void main(String args[]){
        Dog dog = new Dog("Bosse", 3, "Terrier", "Brun");
        Dog dog2 = new Dog("Båtsman", 5, "Sankt Bernhard", "Svart");

        SubDog subDog = new SubDog("Bolt", 2, "Schäfer", "vit");

        dog.sleep();
        dog2.sleep();
        subDog.sleep();

    }

}

class SubDog extends Dog {

    // Subklassens konstruktor
    SubDog(String name, int age, String breed, String color) {
        super(name, age, breed, color);
    }

    void sleep(){
        System.out.println(this.name + ": Jag tänker inte sova!");
    }
}

Vi kollar först på subklassen (rad 45-55):

class SubDog extends Dog {
    
    // Subklassens konstruktor
    SubDog(String name, int age, String breed, String color) {
        super(name, age, breed, color);
    }

    void sleep(){
        System.out.println(this.name + ": Jag tänker inte sova!");
    }
}

Det vi gör är att vi skapar subklassen med namnet SubDog. Vi ärver sedan klassen Dog med nyckelordet extends. Det som händer är att i subklassens, alltså SubDog, konstruktor så anger man nyckelordet super (rad 49) som anropar konstruktorn i superklassen Dog. Viktigt att komma ihåg att inparametrarna måste alltså vara densamma som inparametrarna till superklassen

En klass som ärver kod kallas för subklass och dess förälder för superklass.

Nästa, på rad 52 till 54 så ändrar vi metoden sleep() till en ny önskad kod. För att skapa ett objekt i en subklass så gör vi på exakt samma sätt som vi såg tidigare för att skapa objekt i Java. Om vi sedan låter varje objekt anropa metoden sleep() så blir resultatet:

Bosse: zZZzzZzzZ 
Båtsman: zZZzzZzzZ 
Bolt: Jag tänker inte sova!

Självklart finns även superklassens andra metoder kvar i subklassen, exempelvis metoden eat().

subDog.eat();

Som resulterar i utskriften:

Bolt äter

Önskar man att lägga till klassvariabler och nya metoder görs det enkelt genom att lägga till dem i subklassen:

class SubDog extends Dog {
    public int velocity;
    SubDog(String name, int age, String breed, String color, int velocity) {
        super(name, age, breed, color);
        this.velocity = velocity;
    }

    void sleep(){
        System.out.println(this.name + ": Jag tänker inte sova!");
    }

    void run(){
        System.out.println(this.name + ": springer med hastigheten " + getVelocity() + "km/h");
    }
    int getVelocity(){
        return this.velocity;
    }
}

Notera att nu kräver subklassen fem inparametrar och vi kan nu skapa ett objekt från subklassen “SuperDog” enligt:

SubDog subDog = new SubDog("Bolt", 2, "Schäfer", "vit", 10);

Vidare, anropar man nu metoden run() enligt:

subDog.run();

Avslutningsvis så blir utskriften;

Bolt: springer med hastigheten 10km/h

Sammanfattning: Arv i Java

Arv (engelska: inheritance) använder man för att återanvända kod från andra klasser. När man använder arv brukar man dela klasserna man använder i två typer:

  1. Subklass: en klass som ärver från en annan klass kallas för en subklass, eller för ett barn/child
  2. Superklass: den klass som arvet sker från kallas för en superklass, eller förälder

Det som sker vid ett arv är att subklassen får samma uppsättning av instansvariabler och metoder som superklassen, men det är självklart möjligt att lägga till nya metoder och klassvariabler om så önskas. Avslutningsvis, för att skapa arv i Java använder man nyckelordet extends följt av namnet på den klass som man vill ärva från. Nyckelordet extends anger att du skapar en ny klass som härrör från en befintlig klass.

Vanliga frågor och svar: Arv i Java

Hur skapar man arv i Java?

Vi använder nyckelordet extends för att skapa ett arv i Java. Nyckelordet extends anger att du skapar en ny klass som härrör från en befintlig klass. Det man gör är att deklarera den subklass som man vill skapa, följt av nyckelordet extends och namnet på den superklass som subklassen ska ärva ifrån.

Vad menas med nyckelordet super?

Nyckelordet super används för att kalla på konstruktorn i superklassen. Det betyder att det är med hjälp av nyckelordet super som vi kan referera till variabler i superklassen från subklassen. 

Varför stöds inte multipla arv i Java?

För att minska komplexiteten och förenkla språket stöds inte så kallade multipla, eller flertalet, arv i Java.

Vad tyckte du om sidan?

Lämna gärna feedback och hjälp oss göra sidan bättre

Feedback gör oss bättre!

Lämna gärna feedback om vad du tyckte om avsnittet!