Arvutiteaduse instituut
  1. Kursused
  2. 2025/26 sügis
  3. Programmeerimine (LTAT.03.001)
EN
Logi sisse

Programmeerimine 2025/26 sügis

  • Üldinfo
  • 1. Muutuja ja avaldis
  • 2. Tingimuslause
  • 3. Funktsioon
  • 4. Korduslause
  • 5. Sõned. Lihtsam failitöötlus
  • 6. Kontrolltöö 1
  • 7. Järjend
  • 8. Järjend 2
  • 9. Kahekordne tsükkel. Failitöötlus
  • 10. Andmestruktuurid
  • 11. Andmestruktuurid 2
  • 12. Kontrolltöö 2
  • 13. Objektorienteeritud programmeerimine
  • 14. Objektorienteeritud programmeerimine 2
14.1 Objektorienteeritud programmeerimine 2
14.2 Kodutöö
14.3 Harjutused
14.4 Silmaring: helitöötlus ja -süntees
  • 15. Rekursioon
  • 16. Kordamine. Projektide esitlused
  • Viiteid
  • Silmaringimaterjalid
  • Materjalid

Objektorienteeritud programmeerimine 2

Eelmises peatükis uurisime lähemalt, kuidas luua klasse ja defineerida klassi konstruktorit, meetodeid ja muutujaid. Seni aga puuduvad meil teadmised, kuidas efektiivselt luua klasse, mis on sisu poolest väga sarnased, ent sisaldavad väikseid eripärasid. Selles peatükis uurime, kuidas luua alam- ja ülemklasse, mis on pärilus ja polümorfism ning kuidas mugavamalt objekti infot väljastada.

Alam- ja ülemklass

Erinevaid klasse luues võib meil tekkida olukord, kus tahame luua klasse, mis on sarnased, ent nendes esineb eripärasid. Hetkel peaksime kõik klassid looma eraldi ja defineerima kõikides klassides eraldi meetodid. Selleks, et seda tööd lihtsustada, saame kasutada alam- ja ülemklasse. Alamklassid on klassid, mis pärivad kõik muutujad ja meetodid ülemklassidest.

Selleks, et luua alamklasse, on meil kõigepealt vaja luua üks ülemklass. Loome allpool klassi Koer, mille isenditel on järgmised omadused: nimi, vanus ja lemmiksöök. Lisaks defineerime meetodi hääl, mis tagastab koera haukumise hääle.

class Koer:

    def __init__(self, nimi, vanus, lemmiksöök):
        self.nimi = nimi
        self.vanus = vanus
        self.lemmiksöök = lemmiksöök

    def hääl(self):
        return "Auh Auh"

Ülemklassi loomise järel saame nüüd ka luua alamklasse. Alamklassi loomiseks on vaja defineerida uus klass unikaalse nimega ja panna klassi nime järele sulud, mille sees on ülemklassi nimi. Meie näites on ülemklassiks Koer, seega sulgudesse peab lisama selle. Kui alamklassi midagi ei lisata, siis peab sisuks kirjutama võtmesõna pass.

Loome kaks ülemklassi Koer alamklassi, mille nimedeks on kaks erinevat koeratõugu, näiteks KingCharlesCavalierSpaniel ja SaksaLambakoer.

class KingCharlesCavalierSpaniel(Koer):
    pass

class SaksaLambakoer(Koer):
    pass

Loome nüüd mõned alamklasside isendid ja vaatame, mis funktsionaalsus neile ülemklassist pärineb.

carlos = KingCharlesCavalierSpaniel("Carlos", 4, "vorst")
ralf = SaksaLambakoer("Ralf", 2, "kohupiim")

print(carlos.hääl())
print(carlos.nimi)
print()
print(ralf.hääl())
print(ralf.lemmiksöök)
 Auh Auh
 Carlos

 Auh Auh
 kohupiim

Pärilus ja polümorfism

Eelmise näite lõpus puutusime esmakordselt kokku pärilusega (ingl inheritance). Päriluse abi saab alamklass kasutada ülemklassi muutujaid ja meetodeid, st need pärandatakse ülemklassilt alamklassile. Selleks, et klass saaks teise klassi meetodeid ja muutujaid pärida, on vaja alamklassi defineerides lisada pärast klassi nime sulud, kuhu lisatakse ülemklassi nimi.

Alamklassid saavad kasutada kõiki meetodeid, mis on defineeritud ülemklassis, aga vajadusel ka lisada uusi meetodeid, mis on unikaalsed selle alamklassi jaoks ja üle katta (st üle kirjutada, ingl. override) ülemklassi meetodeid.

Koerte näites nägime, et alamklassid pärisid ülemklassist meetodi hääl ja samuti kõik ülemklassi muutujad. Proovime nüüd samades alamklassides luua uusi meetodeid ja üle katta ülemklassi meetodi.

class KingCharlesCavalierSpaniel(Koer):

    def jalutama(self, pikkus_km):
        aeg = pikkus_km / 10 * 60
        return round(aeg)

class SaksaLambakoer(Koer):

    def hääl(self):
        return "Vuff Vuff"

carlos = KingCharlesCavalierSpaniel("Carlos", 4, "vorst")
ralf = SaksaLambakoer("Ralf", 2, "kohupiim")

print(f"Carlose jalutuskäik kestis {carlos.jalutama(10)} minutit.")
print(f"Carlose hääl: {carlos.hääl()}")
print()
print(f"Ralfi hääl: {ralf.hääl()}")
 Carlose jalutuskäik kestis 60 minutit.
 Carlose hääl:  Auh Auh

 Ralfi hääl:  Vuff Vuff

Näeme, et alamklassi SaksaLambakoer isendite puhul erineb meetod hääl ülemklassi omast, sest katsime selle üle. Lisasime ka alamklassile KingCharlesCavalierSpaniel meetodi jalutama, mis on täiesti unikaalne selle alamklassi jaoks: seda ei leidu ei ülemklassis Koer ega ka teises alamklassis SaksaLambaKoer.

Ülemklassi meetodite ülekatmist nimetatakse polümorfismiks. Polümorfism tähendab, et ülemklassis defineeritud meetod on alamklassis üle kirjutatud ja seetõttu käitub alamklassi isend erinevalt. Polümorfism on kasulik, kui meil on vaja, et ülemklassis olevad meetod(id) käituksid erinevalt alamklasside meetodist. Alamklassis SaksaLambakoer ülekaetud meetod hääl on näide polümorfismist.

Enesekontroll

Meetod __str__

Pärast klassi isendi loomist võib tekkida vajadus väljastada ekraanile info loodud klassi isendi kohta. Proovime väljastada ekraanile klasside KingCharlesCavalierSpaniel ja SaksaLambakoer isendid.

carlos = KingCharlesCavalierSpaniel("Carlos", 4, "vorst")
ralf = SaksaLambakoer("Ralf", 2, "kohupiim")

print(carlos)
print(ralf)
 <__main__.KingCharlesCavalierSpaniel object at 0x04090DD0>
 <__main__.SaksaLambakoer object at 0x03640DF0>

Näeme, et klassi isendi printimisel tekib ekraanile segane tekst, justkui krüpteeritud kujul. Tegelikkuses väljastatakse ekraanile klassi isendi tüüp ning tema asukoht arvuti mälus. Kuid sellisest väljundist pole meie jaoks mingit abi. Selleks, et klassi isendite kohta väljastada vajalikku infot, võiksime luua meetodi nimega __str__.

Meetod __str__ hoolitseb selle eest, mis väljastatakse ekraanile klassi isendi printimisel. Selleks oleks mõistlik defineerida ülemklassis Koer meetod __str__, mis tagastab (return) isendi info soovitud kujul ja see pärandatakse kõikidesse alamklassidesse.

class Koer:

    def __init__(self, nimi, vanus, lemmiksöök):
        self.nimi = nimi
        self.vanus = vanus
        self.lemmiksöök = lemmiksöök

    def hääl(self):
        return "Auh Auh"

    def __str__(self):
        return f"{self.nimi} on {self.vanus} aastat vana ning tema lemmiksöök on {self.lemmiksöök}"

carlos = KingCharlesCavalierSpaniel("Carlos", 4, "vorst")
ralf = SaksaLambakoer("Ralf", 2, "kohupiim")

print(carlos)
print(ralf)
 Carlos on 4 aastat vana ning tema lemmiksöök on vorst
 Ralf on 2 aastat vana ning tema lemmiksöök on kohupiim

Nüüd klassi isendit printides väljastatakse ekraanile isendi kohta loogiline info.

Selleks, et tagastada kogu info klassi isendi kohta ühe sõnena, on siin kasutatud Pythoni vormindatud sõnet (ingl formatted string ehk f-string). Nii saame lisada muutujaid otse sõne sisse ümbritsetud looksulgudega, ilma sõnet tükkideks jagamata.

Ülemklassi konstruktori väljakutsumine

Vahel on vaja alamklassis välja kutsuda hoopis ülemklassi konstruktorit. Teeme siinkohal sellise näite, et kõik saksa lambakoerad saavad automaatselt nimeks Rex. Sellisel juhul saame saksa lambakoera klassis kasutada ülemklassi Koer konstruktorit käsklusega super():

class SaksaLambakoer(Koer):
    def __init__(self, nimi, vanus, lemmiksöök):
        super().__init__("Rex", vanus, lemmiksöök)

    def hääl(self):
        return "Vuff Vuff"

Sellisel juhul juhtub see, et hoolimata sellest, kui panime saksa lambakoerale nimeks näiteks Ralf, saab ta nimeks ikkagi Rex.

Video

Järgmises videos on selgitatud edasi objektorienteeritud programmeerimise põhimõtteid.

  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused