Sobes.tech
Middle

V ktorých situáciách je dedičstvo v objektovo orientovanom programovaní užitočné a kedy by sa od neho malo upustiť?

sobes.tech AI

Odpoveď od AI

Dedičnosť je užitočná pre:

  • Opakované použitie kódu: Spoločná funkcionalita sa presúva do základnej triedy.
  • Vytváranie hierarchií typov (vzťah is-a): Keď odvodná trieda je variáciou základnej triedy.
  • Polymorfizmus: Možnosť spracovávať objekty rôznych typov cez spoločné rozhranie základnej triedy.
  • Rozšírenie funkčnosti: Pridanie nových metód alebo polí do existujúcej triedy.

Vyhnite sa dedičstvu, keď:

  • Porušuje sa princíp Liskovovej substitúcie: Odvodná trieda nemôže úplne nahradiť základnú triedu bez zmeny správnosti programu.
  • Vytvára sa pevné spojenie medzi triedami: Zmeny v základnej triede môžu nežiadaným spôsobom ovplyvniť všetky odvodené triedy.
  • Je potrebné kombinovať funkcionalitu z rôznych, nesúvisiacich zdrojov (has-a vzťah): Je lepšie použiť kompozíciu.
  • Hierarchia je príliš zložitá: Hlboké reťazce dedičnosti sú ťažko udržiavateľné a pochopiteľné.
  • Dedičstvo na opätovné použitie kódu, keď funkčnosť nie je spoločným "typom": Je lepšie použiť pomocné triedy alebo delegáciu.
// Príklad, keď je dedičstvo užitočné
open class Animal {
    open fun makeSound() {
        println("Všeobecný zvuk zvieraťa")
    }
}

class Dog : Animal() { // Dog JE-JEDEN Animal
    override fun makeSound() {
        println("Haf")
    }
}

class Cat : Animal() { // Cat JE-JEDEN Animal
    override fun makeSound() {
        println("Mňau")
    }
}
// Príklad, keď je vhodnejšia kompozícia ako dedičstvo pre vzťah "has-a"
class Engine {
    fun start() { println("Motor spustený") }
}

// Namiesto dedičstva od Engine pre Car
// class Car : Engine() // Zlý dizajn, Car NIE JE-Engine

class Car {
    private val engine = Engine() // Car má-Engine
    fun drive() {
        engine.start()
        println("Auto jazdí")
    }
}