Scala för backendutveckling och funktionell programmering · Lektion

Arv och polymorfism

Utforska objektorienterade principer som arv, abstrakta klasser och polymorfism i Scala.

Lektion 2 av 211 steg

Arv och polymorfism är en gratis lektion i Scala för backendutveckling och funktionell programmering på CoddyKit. Detta är lektion 2 av 2. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Scala för backendutveckling och funktionell programmering, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Scala för backendutveckling och funktionell programmering innehåller totalt 2 lektioner.

Vad är arv?

Arv är ett grundläggande koncept inom objektorienterad programmering (OOP) som gör att en ny klass kan ärva egenskaper och beteenden (metoder) från en befintlig klass.

Tänk på det som en relation mellan ”förälder” och ”barn”. ”Barnklassen” (underklassen) återanvänder kod från ”föräldraklassen” (superklassen), vilket sparar tid och säkerställer enhetlighet.

  • Främjar återanvändning av kod.
  • Skapar en ”är-en”-relation (till exempel är en Dog ett Animal).
  • Hjälper till att organisera kod i en hierarki.

Din första basklass

Låt oss definiera en enkel klass Animal. Det här blir vår basklass, även kallad superklass eller föräldraklass. Den har ett grundläggande beteende: att tala.

Kör koden för att se vårt generiska djur i aktion!

class Animal {
  val name: String = "Generic Animal"
  def speak(): Unit = {
    println(s"$name makes a sound.")
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val myAnimal = new Animal()
    myAnimal.speak()
  }
}

Utöka med `extends`

Nu skapar vi ett mer specifikt djur, en Dog. En Dog är ett Animal, så den kan ärva från klassen Animal med nyckelordet extends.

Vi kan också åsidosätta metoden speak för att ge Dog ett eget unikt läte. Lägg märke till nyckelordet override.

class Animal {
  val name: String = "Generic Animal"
  def speak(): Unit = {
    println(s"$name makes a sound.")
  }
}

class Dog extends Animal {
  override val name: String = "Dog"
  override def speak(): Unit = {
    println(s"$name barks!")
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val myAnimal = new Animal()
    val myDog = new Dog()
    myAnimal.speak() // Generic Animal makes a sound.
    myDog.speak()    // Dog barks!
  }
}

Kraften i `override`

Nyckelordet override är viktigt i Scala av flera skäl:

  • Tydlighet: Det talar uttryckligen om för andra utvecklare att den här metoden eller det här fältet ersätter en medlem från en superklass.
  • Säkerhet: Kompilatorn kontrollerar att du faktiskt åsidosätter en befintlig medlem. Om du skriver fel eller om superklassens metod ändras får du en varning från kompilatorn.
  • Avsikt: Det tydliggör att du vill specialisera eller ändra ett ärvt beteende.

Använd alltid override när du omdefinierar ärvda medlemmar!

Polymorfism: många former

Polymorfism betyder ”många former”. Inom OOP gör det att objekt från olika klasser kan behandlas som objekt av en gemensam superklass.

Det innebär att du kan ha en variabel av typen Animal som innehåller ett objekt av typen Dog, ett objekt av typen Cat eller någon annan underklass till Animal. När du anropar en metod på den variabeln körs rätt metod för det faktiska objektets typ.

  • Möjliggör flexibel och utbyggbar kod.
  • Gör det möjligt att använda ett enda gränssnitt för olika datatyper.
  • Uppnås genom att metoder åsidosätts.

Polymorfism i praktiken

Låt oss se polymorfism i praktiken. Vi skapar en klass Cat som liknar Dog. Sedan kan vi lägga olika typer av djur i en lista med deras gemensamma supertyp, Animal, och anropa deras metod speak.

Lägg märke till hur varje djur låter på sitt eget unika sätt, trots att alla behandlas som typen Animal i listan.

class Animal {
  val name: String = "Generic Animal"
  def speak(): Unit = {
    println(s"$name makes a sound.")
  }
}

class Dog extends Animal {
  override val name: String = "Dog"
  override def speak(): Unit = {
    println(s"$name barks!")
  }
}

class Cat extends Animal {
  override val name: String = "Cat"
  override def speak(): Unit = {
    println(s"$name meows!")
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val animals: List[Animal] = List(
      new Animal(),
      new Dog(),
      new Cat()
    )

    animals.foreach(_.speak())
  }
}

Introduktion till abstrakta klasser

Ibland vill du ha en basklass som definierar ett gemensamt gränssnitt men inte tillhandahåller en fullständig implementation för alla sina medlemmar. Det är här abstrakta klasser kommer in.

En abstrakt klass:

  • Kan inte instansieras direkt (du kan inte skapa ett objekt av en abstrakt klass).
  • Kan innehålla abstrakta metoder (metoder utan implementation) och konkreta metoder (metoder med implementation).
  • Fungerar som en ritning som dess underklasser måste komplettera.

Skapa abstrakta ritningar

Låt oss definiera en abstract class Shape. Varje form har en area, men formeln för att beräkna den skiljer sig åt för varje specifik form (cirkel, rektangel och så vidare).

Därför deklarerar vi area som en abstrakt metod. Lägg märke till att den saknar kropp (ingen = { ... }). Underklasserna ansvarar för att tillhandahålla dess implementation.

abstract class Shape {
  def area: Double // Abstract method, no implementation
  
  def describe(): Unit = {
    println("This is a geometric shape.")
  }
}

// You cannot do: new Shape() - it's abstract!

object Main {
  def main(args: Array[String]): Unit = {
    println("Abstract class Shape defined.")
    println("Cannot instantiate Shape directly.")
  }
}

Konkreta implementationer

Nu skapar vi konkreta underklasser som Circle och Rectangle som utökar vår abstract class Shape. Dessa underklasser måste tillhandahålla en implementation av den abstrakta metoden area.

De ärver också den konkreta metoden describe() från Shape.

abstract class Shape {
  def area: Double
  def describe(): Unit = {
    println("This is a geometric shape.")
  }
}

class Circle(radius: Double) extends Shape {
  override def area: Double = math.Pi * radius * radius
}

class Rectangle(width: Double, height: Double) extends Shape {
  override def area: Double = width * height
}

object Main {
  def main(args: Array[String]): Unit = {
    val circle = new Circle(5)
    val rectangle = new Rectangle(4, 6)

    println(s"Circle area: ${circle.area}")
    circle.describe()
    println(s"Rectangle area: ${rectangle.area}")
    rectangle.describe()
  }
}

Kontroll av arv och polymorfism

Vilka av följande påståenden om arv och polymorfism i Scala är sanna?

Sammanfattning: arv och polymorfism

Bra jobbat! I den här lektionen har vi gått igenom centrala OOP-koncept i Scala:

  • Arv: Hur underklasser återanvänder kod och skapar en ”är-en”-relation med superklasser med hjälp av extends.
  • Nyckelordet override: Viktigt för att uttryckligen omdefiniera ärvda metoder och fält, vilket säkerställer typsäkerhet och tydlighet.
  • Polymorfism: Möjligheten att behandla objekt från olika underklasser som objekt av en gemensam superklass, vilket möjliggör flexibel och utbyggbar kod.
  • Abstrakta klasser: Ritningar som inte kan instansieras direkt och som används för att definiera gemensamma gränssnitt och abstrakta medlemmar som underklasser måste implementera.

De här koncepten är viktiga när du bygger välstrukturerade och lättunderhållna Scala-applikationer!

Gratis att börja

Lär dig Scala med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
39
Lektioner
143

Vanliga frågor

Är lektionen ”Arv och polymorfism” gratis?

Ja – hela texten till ”Arv och polymorfism” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Scala för backendutveckling och funktionell programmering, kan Ni uppgradera till CoddyKit PRO. Kursen i Scala för backendutveckling och funktionell programmering innehåller totalt 2 lektioner.

Vad lär jag mig i ”Arv och polymorfism”?

Utforska objektorienterade principer som arv, abstrakta klasser och polymorfism i Scala. Ni övar på Scala för backendutveckling och funktionell programmering med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Scala för backendutveckling och funktionell programmering?

Du behöver inga förkunskaper. Utbildningen i Scala för backendutveckling och funktionell programmering på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 2.

Hur lång tid tar lektionen ”Arv och polymorfism”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Scala för backendutveckling och funktionell programmering-lektionen?

Ja. Varje Scala för backendutveckling och funktionell programmering-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Klasser, objekt och paketering
  2. Arv och polymorfism
← Tillbaka till Scala för backendutveckling och funktionell programmering