{"id":928,"date":"2023-01-02T09:04:11","date_gmt":"2023-01-02T09:04:11","guid":{"rendered":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/?post_type=chapter&#038;p=928"},"modified":"2023-01-02T13:35:27","modified_gmt":"2023-01-02T13:35:27","slug":"objektid-ja-klassid","status":"publish","type":"chapter","link":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/chapter\/objektid-ja-klassid\/","title":{"raw":"Objektid ja klassid","rendered":"Objektid ja klassid"},"content":{"raw":"Kuigi Python toetab mitut programmeerimise paradigmat, on neist k\u00f5ige enam r\u00f5hutatud just objekt-orienteeritud programmeerimise (OOP) paradigmat.\r\nV\u00f5ib \u00f6elda, et OOP-i kasutamine t\u00e4hendab programmikoodi teatud kindlal viisil organiseerimist. Selle l\u00e4henemise juures leiavad kasutamist\r\nm\u00f5isted nagu <strong>klass<\/strong> ja <strong>objekt<\/strong>, teemasse enam s\u00fcvenedes ka <em>kapseldamine<\/em>, <em>pol\u00fcmorfism<\/em>, <em>p\u00e4rimine<\/em>, <em>modulaarsus<\/em>, <em>abstraktsioon<\/em>. Viimaseid\r\nnimetatakse OOP tehnikateks.\r\n\r\nOOP-i juures on tavaline r\u00e4\u00e4kida klasside kirjeldamisest ja nende kirjelduste alusel objektide loomisest ning manipuleerimisest. Objektidega\r\nmanipuleerimine leiab aset klassi kirjelduses antud meetodite (p\u00f5him\u00f5tteliselt funktsioonide) alusel. Klassi kirjelduse alusel luuakse objekte,\r\nmillistel on \u00fchesugused omadused ja tegevused (meetodid).\r\n\r\nVaata allj\u00e4rgnevast videost, mis on objekt-orienteeritud programmeerimine, mis on klassid ja objektid ning vaata n\u00e4iteid erinevatest OOP tehnikatest.\r\n\r\n[embed]https:\/\/www.youtube.com\/embed\/J2AfozE6lGo[\/embed]\r\n\r\n<a href=\"https:\/\/pydoc.pages.taltech.ee\/slides\/oop\/\">Videos kasutatud slaidid<\/a>\r\n\r\nJ\u00e4rgneva n\u00e4ite pideva t\u00e4iendamisega p\u00fc\u00fcame samm-sammult antud teema olulised ideed edasi anda.\r\n\r\nOletame, et tahame koostada programmi, mis simuleerib tavalise koera k\u00e4itumist. Mida oskab tavaline koer?\r\nEeldame, et iga tavaline koer oskab haukuda, veereda ja tervitada oma omanikku. Samal ajal, tavaline koer ei oska r\u00e4\u00e4kida (\u00fcsna\r\nloogiline, eks). Selleks, et koostada sellist programmi, defineerime klassi <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code> (mille alusel saab hiljem programmis just samade, klassis kirjeldatud,\r\noskustega koeri luua):\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># Defining the Dog class\r\nclass Dog:\r\n    # Code\r\n<\/pre>\r\nOn teada, et iga tavaline koer oskab haukuda, veereda ja tervitada oma omanikku:\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    def bark(self):\r\n        print(\"Bark!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(\"Hey, master\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot!\")\r\n<\/pre>\r\n&nbsp;\r\n\r\nKlassi <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code> kirjelduses on neli funktsiooni, mida OOP l\u00e4henemise puhul nimetatakse klassi <strong>meetoditeks<\/strong>. P\u00f6\u00f6rame t\u00e4helepanu, et iga\r\nmeetod kasutab parameetrit nimega <code class=\"docutils literal notranslate\"><span class=\"pre\">self<\/span><\/code>, millest r\u00e4\u00e4gime natuke hiljem. Meie klass kirjeldab <em>tavalise koera<\/em>\r\nk\u00e4itumist - on meetodid, mis paiknevad klassi sees ning kirjeldavad iga <em>tavalise koera<\/em> oskusi. See ongi abstraktsioon. S.t. klass (meil <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code>)\r\non kui piparkoogivorm ning objektid kui antud vormiga tehtud piparkoogid.\r\nN\u00fc\u00fcd, kui meil on klassis tavalise koera k\u00e4itumine kirjeldatud, saab luua objekti - klassi isendi (instance).\r\nLoome kaks koera: <code class=\"docutils literal notranslate\"><span class=\"pre\">Clyde<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">Jenkins<\/span><\/code>.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    def bark(self):\r\n        print(\"Woof!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(\"Greetings, master\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot!\")\r\n\r\n# Creating the Dog class instance and saving it to the variable &lt;clyde&gt;\r\nclyde = Dog()\r\nclyde.bark()   # --&gt; Woof!\r\nclyde.roll()   # --&gt; *rolling*\r\nclyde.greet()  # --&gt; Greetings, master\r\nclyde.speak()  # --&gt; I cannot!\r\n\r\n# Creating another Dog instance\r\njenkins = Dog()\r\njenkins.bark()  # --&gt; Woof!\r\njenkins.roll()  # --&gt; *rolling*\r\n# .. And other methods\r\n# .. Infinite objects can be created this way, all implementing the same methods defined in our class\r\n<\/pre>\r\n&nbsp;\r\n\r\nTuleb v\u00e4lja, et vaatamata sellele, et <code class=\"docutils literal notranslate\"><span class=\"pre\">clyde<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">jenkins<\/span><\/code> on erinevad koerad, oskavad m\u00f5lemad teha asju,\r\nmida meie definitsiooni j\u00e4rgi oskab iga tavaline koer. Nii, nagu reaalses elus umbes ongi - n\u00e4iteks iga koer oskab haukuda\r\ns\u00f5ltumata tema liigist.\r\n\r\nKlassil v\u00f5ib olla ka <strong>konstruktor<\/strong>, mis kujutab endast erilist, fikseeritud nimega, meetodit klassi sees. See fikseeritud nimi on j\u00e4rgmine:\r\n<strong>__init__()<\/strong>.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n    # Class constructor\r\n    def __init__(self):\r\n        # Code here\r\n<\/pre>\r\nKonstruktor ja selle sees olev kood k\u00e4ivitatakse <strong>vaid isendi (objekti) loomisel<\/strong>. N\u00e4iteks tahame, et klassi <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code>\r\nisendi loomisel oleks igale klassi objektile antud oma nimi. Teeme nii, et meie konstruktor v\u00f5taks sisse teise argumendi,\r\n<code class=\"docutils literal notranslate\"><span class=\"pre\">name<\/span><\/code>, ja salvestaks selle uue muutuja <code class=\"docutils literal notranslate\"><span class=\"pre\">self.name<\/span><\/code> sisse.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    # Class constructor\r\n    def __init__(self, name):\r\n        self.name = name\r\n\r\n    def bark(self):\r\n        print(\"Woof!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(\"Greetings, master\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot!\")\r\n\r\n    # Returns the current dog's name\r\n    def get_name(self):\r\n        return self.name\r\n\r\n    # Returns the reference to the current dog instance\r\n    def get_this_dog(self):\r\n        return self\r\n\r\n# Creating the Dog class instance and giving it name\r\ndog1 = Dog(\"Clyde\")\r\ndog1.bark()  # --&gt; Woof!\r\ndog1.roll()  # --&gt; *rolling*\r\ndog1.greet() # --&gt; Greetings, master\r\ndog1.speak() # --&gt; I cannot!\r\nprint(dog1.get_name())  # --&gt; Clyde\r\nprint(dog1.get_this_dog())  # --&gt; (Example) &lt;__main__.Dog object at 0x0119D710&gt;\r\nprint(dog1)  # --&gt; (Example) &lt;__main__.Dog object at 0x0119D710&gt;\r\n\r\n# Creating some more Dog instances\r\ndog2 = Dog(\"Jenkins\")\r\ndog2.bark() # --&gt; Woof!\r\ndog2.roll()  # --&gt; *rolling*\r\ndog2.greet() # --&gt; Greetings, master\r\ndog2.speak() # --&gt; I cannot!\r\nprint(dog2.get_name())  # --&gt; Jenkins\r\nprint(dog2.get_this_dog())  # --&gt; (Example) &lt;__main__.Dog object at 0x0143D710&gt;\r\nprint(dog2)  # --&gt; (Example) &lt;__main__.Dog object at 0x0143D710&gt;\r\n\r\ndog3 = Dog(\"Robbie\")\r\nprint(dog3.get_name())  # --&gt; Robbie\r\nprint(dog3.get_this_dog())  # --&gt; (Example) &lt;__main__.Dog object at 0x01CED710&gt;\r\n<\/pre>\r\n&nbsp;\r\n\r\nSeega, vaatamata sellele, et iga koer oskab haukuda, veereda ja tervitada, on k\u00f5ik koerad erinevad objektid, nagu\r\nreaalelus ongi. Muutuja <code class=\"docutils literal notranslate\"><span class=\"pre\">self<\/span><\/code> iseloomustab antud juhul just seda konkreetset koera, kelle objekt on loodud,\r\n<code class=\"docutils literal notranslate\"><span class=\"pre\">self<\/span><\/code> on viide sellele objektile. Seda on n\u00e4ha, kui printida v\u00e4lja meie <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code> klassil olev meetod <code class=\"docutils literal notranslate\"><span class=\"pre\">get_this_dog<\/span><\/code>\r\nv\u00f5i kui lihtsalt \u00fcritada v\u00e4lja printida objekti ennast, nagu on \u00fcleval tehtud.\r\nNagu n\u00e4ha, on erinevatel objektidel erinev viide, mis t\u00e4hendabki, et n\u00e4iteks Jenkins ja Clyde ei ole \u00fcks ja sama\r\nkoer, vaid kaks erinevat.\r\nKui meie loome muutuja, pannes <code class=\"docutils literal notranslate\"><span class=\"pre\">self<\/span><\/code> juurde prefiksina, nagu tegime <code class=\"docutils literal notranslate\"><span class=\"pre\">self.name<\/span><\/code> korral, siis saame nn\r\n<strong>isendimuutuja<\/strong>, mis on n\u00e4htav igale klassi meetodile:\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    # Class constructor\r\n    def __init__(self, name):\r\n        # Instance variable\r\n        self.name = name\r\n\r\n    def bark(self):\r\n        print(self.name + \" says: Woof!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(self.name + \" greets you!\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot\")\r\n\r\n    # Returns the current dog's name\r\n    def get_name(self):\r\n        return self.name\r\n\r\n    # Returns the current dog instance\r\n    def get_this_dog(self):\r\n        return self\r\n\r\ndog1 = Dog(\"Clyde\")\r\ndog1.bark()  # --&gt; Clyde says: Woof!\r\ndog1.greet()  # --&gt; Clyde greets you!\r\nprint(dog1.get_name())  # --&gt; Clyde\r\nprint(dog1)  # --&gt; Reference\r\n\r\ndog2 = Dog(\"Jenkins\")\r\ndog2.bark() # --&gt; Jenkins says: Woof!\r\ndog2.greet() # --&gt; Jenkins greets you!\r\nprint(dog2.get_name())  # --&gt; Jenkins\r\n<\/pre>\r\n&nbsp;\r\n\r\nKlassil v\u00f5ib olla ka <strong>klassimuutuja<\/strong>, mis on samal moel n\u00e4htav igale klassi meetodile:\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    # Class variable\r\n    name = \"Some name\"\r\n\r\n    # Class constructor\r\n    def __init__(self, new_name):\r\n        # Assign class variable to new value\r\n        Dog.name = new_name\r\n\r\n    def bark(self):\r\n        print(Dog.name + \" says: Woof!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(Dog.name + \" greets you!\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot\")\r\n\r\n    # Returns the current dog's name\r\n    def get_name(self):\r\n        return Dog.name\r\n\r\n# We do not need to create an object to access the class variable\r\nprint(Dog.name)  # --&gt; Some name\r\n\r\ndog1 = Dog(\"Clyde\")\r\ndog1.bark()  # --&gt; Clyde says: Woof!\r\ndog1.greet()  # --&gt; Clyde greets you!\r\nprint(dog1.get_name())  # --&gt; Clyde\r\nprint(Dog.name)  # --&gt; Clyde\r\n\r\ndog2 = Dog(\"Jenkins\")\r\ndog2.bark() # --&gt; Jenkins says: Woof!\r\ndog2.greet() # --&gt; Jenkins greets you!\r\nprint(dog2.get_name())  # --&gt; Jenkins\r\nprint(Dog.name)  # --&gt; Jenkins\r\n\r\n# Assign new value to the variable name\r\nDog.name = \"Some random dog name\"\r\nprint(Dog.name)  # --&gt; Some random dog name\r\n<\/pre>\r\n&nbsp;\r\n\r\n<strong>Isendimuutuja<\/strong> ja <strong>klassimuutuja<\/strong> erinevad teineteisest selle poolest, et <strong>klassimuutuja<\/strong> eksisteerib, on\r\nk\u00e4ttesaadav ja muudetav ilma objekti loomiseta, kuid samal ajal <strong>isendimuutuja<\/strong> eksisteerib ainult koos oma objektiga.\r\n\r\nVeel m\u00f5ni lihtne n\u00e4ide. Oletame, et me tahame koostada klassi, mis kirjeldaks tavalist tudengit. Igal tudengil\r\non olemas nimi ja kool, kus ta \u00f5pib. Samas on suurem osa tudengeid laisad, aga mitte k\u00f5ik. Ehk igal tudengil\r\non kolm parameetrit: nimi, kool ja laiskus, mis on vaikimisi t\u00f5ene.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Student:\r\n    \"\"\"Student class.\"\"\"\r\n\r\n    def __init__(self, name, college, is_lazy=True):\r\n        \"\"\"\r\n        Class constructor.\r\n\r\n        :param name: student name\r\n        :param college: student college\r\n        :param is_lazy: is student lazy? (by default yes)\r\n        \"\"\"\r\n        self.name = name\r\n        self.college = college\r\n        self.is_lazy = is_lazy\r\n<\/pre>\r\nTudengitel on alati mingi kodut\u00f6\u00f6. Eeldame, et tudeng saab teha homset kodut\u00f6\u00f6d ainult siis, kui ta ei ole laisk.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">def is_homework_done(self):\r\n    \"\"\"\r\n    Did the student do the homework for tomorrow?\r\n\r\n    :return: string\r\n    \"\"\"\r\n    if self.is_lazy:\r\n        return \"Homework? Pff, I have TV shows to watch.\"\r\n\r\n    return \"Homework is done!\"\r\n<\/pre>\r\nLisaks sellele eeldame, et iga tudeng saab oma kooli vahetada.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">def change_college(self, college):\r\n    \"\"\"\r\n    Change the college student attends.\r\n\r\n    :param college:\r\n    :return none\r\n    \"\"\"\r\n    print(\"Student {} leaves the {} and starts studying in {}\".format(self.name, self.college, college))\r\n    self.college = college<\/pre>\r\nJa samal moel saab tudeng m\u00f5istuse p\u00e4he v\u00f5tta ja enam mitte laisk olla (v\u00f5i vastupidi):\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">def change_laziness(self):\r\n    \"\"\"\r\n    Is the student still lazy\/not lazy?\r\n\r\n    :return: none\r\n    \"\"\"\r\n    self.is_lazy = not self.is_lazy<\/pre>\r\nSiis, pannes k\u00f5ik kokku, saame:\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Student:\r\n    \"\"\"Student class.\"\"\"\r\n\r\n    def __init__(self, name, college, is_lazy=True):\r\n        \"\"\"\r\n        Class constructor.\r\n\r\n        :param name: student name\r\n        :param college: student college\r\n        :param is_lazy: is student lazy? (by default - yes)\r\n        \"\"\"\r\n        self.name = name\r\n        self.college = college\r\n        self.is_lazy = is_lazy\r\n\r\n    def is_homework_done(self):\r\n        \"\"\"\r\n        Did the student do the homework for tomorrow?\r\n\r\n        :return: string\r\n        \"\"\"\r\n        if self.is_lazy:\r\n            return \"Homework? Pff, I have TV shows to watch.\"\r\n\r\n        return \"Homework is done!\"\r\n\r\n    def get_college(self):\r\n        \"\"\"\r\n        Get the college student attends.\r\n\r\n        :return: college\r\n        \"\"\"\r\n        return \"{} studies in {}\".format(self.name, self.college)\r\n\r\n    def change_college(self, college):\r\n        \"\"\"\r\n        Change the college students attends.\r\n\r\n        :param college:\r\n        :return none\r\n        \"\"\"\r\n        print(\"Student {} leaves the {} and starts studying in {}\".format(self.name, self.college, college))\r\n        self.college = college\r\n\r\n    def get_name(self):\r\n        \"\"\"\r\n        Get the student name.\r\n\r\n        :return: name\r\n        \"\"\"\r\n        return self.name\r\n\r\n    def get_laziness(self):\r\n        \"\"\"\r\n        Is the student lazy?\r\n\r\n        :return: true\/false\r\n        \"\"\"\r\n        return self.is_lazy\r\n\r\n    def change_laziness(self):\r\n        \"\"\"\r\n        Is the student still lazy\/not lazy?\r\n\r\n        :return: none\r\n        \"\"\"\r\n        self.is_lazy = not self.is_lazy\r\n\r\n# Some examples\r\n\r\nst1 = Student(\"Alice\", \"Tallinn University of Technology\")\r\nprint(st1)  # --&gt; (Example) &lt;__main__.Student object at 0x01E3DB30&gt;\r\nprint(st1.get_name())  # --&gt; Alice\r\nprint(st1.get_college())  # --&gt; Tallinn University of Technology\r\nprint(st1.get_laziness())  # --&gt; True\r\nprint(st1.is_homework_done())  # --&gt; Homework? Pff, I have TV shows to watch.\r\nprint()\r\n\r\n# Alice decides she is more into art than computers, so she leaves TUT and starts studying in Estonian Academy of Arts.\r\n# Output: Student Alice leaves the Tallinn University of Technology and starts studying in Estonian Academy of Arts\r\nst1.change_college(\"Estonian Academy of Arts\")\r\nprint(st1.get_college())  # --&gt; Estonian Academy of Arts\r\n# She is still lazy though\r\nprint(st1.get_laziness())  # --&gt; True\r\nprint()\r\n\r\nst2 = Student(\"Mary\", \"Massachusetts Institute of Technology\", False)\r\nprint(st2.get_name())  # --&gt; Mary\r\nprint(st2.get_college())  # --&gt; Massachusetts Institute of Technology\r\nprint(st2.get_laziness())  # --&gt; False\r\nprint(st2.is_homework_done())  # --&gt; Homework is done!\r\n# It is weekend now, so Mary can be a bit lazier than usual\r\nst2.change_laziness()\r\nprint(st2.is_homework_done())  # --&gt; Homework? Pff, I have TV shows to watch.<\/pre>\r\nVaatleme lisaks \u00fcht sisseehitatud meetodit, mis teeb meie elu veidi lihtsamaks. Meetodi nimi on <code class=\"docutils literal notranslate\"><span class=\"pre\">__str__<\/span><\/code>. Meetod k\u00e4ivitub\r\nsiis, kui me proovime objekti v\u00e4lja printida ja tagastab meie poolt m\u00e4\u00e4ratud stringi tavalise viite asemel. Vaatame,\r\nkuidas see meetod t\u00f6\u00f6tab <code class=\"docutils literal notranslate\"><span class=\"pre\">Student<\/span><\/code> klassi n\u00e4itel.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Student:\r\n    \"\"\"Student class.\"\"\"\r\n\r\n    def __init__(self, name, college, is_lazy=True):\r\n        \"\"\"\r\n        Class constructor.\r\n\r\n        :param name: student name\r\n        :param college: student college\r\n        :param is_lazy: is student lazy? (by default - yes)\r\n        \"\"\"\r\n        self.name = name\r\n        self.college = college\r\n        self.is_lazy = is_lazy\r\n\r\n    def __str__(self):\r\n        \"\"\"\r\n        Returns name of the student when invoked.\r\n\r\n        :return: student name\r\n        \"\"\"\r\n        return self.name\r\n\r\n    # &lt;...Other methods skipped...&gt;\r\n\r\n\r\n# Some examples\r\n\r\nst1 = Student(\"Alice\", \"Tallinn University of Technology\")\r\nprint(st1)  # --&gt; Alice\r\nprint()\r\n\r\nst2 = Student(\"Mary\", \"Massachusetts Institute of Technology\", False)\r\nprint(st2)  # --&gt; Mary\r\n<\/pre>\r\nEhk n\u00fc\u00fcd ei ole meil vaja luua eraldi meetodit <code class=\"docutils literal notranslate\"><span class=\"pre\">get_name<\/span><\/code> tudengi nime tagastamiseks, nime on v\u00f5imalik saada lihtsalt\r\nobjekti printimisel. <code class=\"docutils literal notranslate\"><span class=\"pre\">__str__<\/span><\/code> ei pea tagastama ainult nime, antud juhul n\u00e4iteks v\u00f5iks ta tagastada ka kooli, kus tudeng \u00f5pib.\r\n\r\n<section id=\"lisalugemist\">\r\n<h2 id=\"lisalugemist\">Lisalugemist<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#lisalugemist\">\uf0c1<\/a><\/h2>\r\n<ul class=\"simple\">\r\n \t<li>\u00dclevaade koos n\u00e4idetega klasside ja objektide kohta W3Schools <a class=\"reference external\" href=\"https:\/\/www.w3schools.com\/python\/python_classes.asp\">Python Classes and Objects<\/a> peat\u00fckis.<\/li>\r\n \t<li>Klasside ja objektide kasutamise p\u00f5him\u00f5tted ja n\u00e4ited GeeksforGeeks <a class=\"reference external\" href=\"https:\/\/www.geeksforgeeks.org\/python-classes-and-objects\/\">Python Classes and Objects<\/a> artiklis.<\/li>\r\n<\/ul>\r\n<\/section>","rendered":"<p>Kuigi Python toetab mitut programmeerimise paradigmat, on neist k\u00f5ige enam r\u00f5hutatud just objekt-orienteeritud programmeerimise (OOP) paradigmat.<br \/>\nV\u00f5ib \u00f6elda, et OOP-i kasutamine t\u00e4hendab programmikoodi teatud kindlal viisil organiseerimist. Selle l\u00e4henemise juures leiavad kasutamist<br \/>\nm\u00f5isted nagu <strong>klass<\/strong> ja <strong>objekt<\/strong>, teemasse enam s\u00fcvenedes ka <em>kapseldamine<\/em>, <em>pol\u00fcmorfism<\/em>, <em>p\u00e4rimine<\/em>, <em>modulaarsus<\/em>, <em>abstraktsioon<\/em>. Viimaseid<br \/>\nnimetatakse OOP tehnikateks.<\/p>\n<p>OOP-i juures on tavaline r\u00e4\u00e4kida klasside kirjeldamisest ja nende kirjelduste alusel objektide loomisest ning manipuleerimisest. Objektidega<br \/>\nmanipuleerimine leiab aset klassi kirjelduses antud meetodite (p\u00f5him\u00f5tteliselt funktsioonide) alusel. Klassi kirjelduse alusel luuakse objekte,<br \/>\nmillistel on \u00fchesugused omadused ja tegevused (meetodid).<\/p>\n<p>Vaata allj\u00e4rgnevast videost, mis on objekt-orienteeritud programmeerimine, mis on klassid ja objektid ning vaata n\u00e4iteid erinevatest OOP tehnikatest.<\/p>\n<p><iframe loading=\"lazy\" id=\"oembed-1\" title=\"Objekt-orienteeritud programmeerimine\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/J2AfozE6lGo?feature=oembed&#38;rel=0\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p><a href=\"https:\/\/pydoc.pages.taltech.ee\/slides\/oop\/\">Videos kasutatud slaidid<\/a><\/p>\n<p>J\u00e4rgneva n\u00e4ite pideva t\u00e4iendamisega p\u00fc\u00fcame samm-sammult antud teema olulised ideed edasi anda.<\/p>\n<p>Oletame, et tahame koostada programmi, mis simuleerib tavalise koera k\u00e4itumist. Mida oskab tavaline koer?<br \/>\nEeldame, et iga tavaline koer oskab haukuda, veereda ja tervitada oma omanikku. Samal ajal, tavaline koer ei oska r\u00e4\u00e4kida (\u00fcsna<br \/>\nloogiline, eks). Selleks, et koostada sellist programmi, defineerime klassi <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code> (mille alusel saab hiljem programmis just samade, klassis kirjeldatud,<br \/>\noskustega koeri luua):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># Defining the Dog class\r\nclass Dog:\r\n    # Code\r\n<\/pre>\n<p>On teada, et iga tavaline koer oskab haukuda, veereda ja tervitada oma omanikku:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    def bark(self):\r\n        print(\"Bark!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(\"Hey, master\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot!\")\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Klassi <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code> kirjelduses on neli funktsiooni, mida OOP l\u00e4henemise puhul nimetatakse klassi <strong>meetoditeks<\/strong>. P\u00f6\u00f6rame t\u00e4helepanu, et iga<br \/>\nmeetod kasutab parameetrit nimega <code class=\"docutils literal notranslate\"><span class=\"pre\">self<\/span><\/code>, millest r\u00e4\u00e4gime natuke hiljem. Meie klass kirjeldab <em>tavalise koera<\/em><br \/>\nk\u00e4itumist &#8211; on meetodid, mis paiknevad klassi sees ning kirjeldavad iga <em>tavalise koera<\/em> oskusi. See ongi abstraktsioon. S.t. klass (meil <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code>)<br \/>\non kui piparkoogivorm ning objektid kui antud vormiga tehtud piparkoogid.<br \/>\nN\u00fc\u00fcd, kui meil on klassis tavalise koera k\u00e4itumine kirjeldatud, saab luua objekti &#8211; klassi isendi (instance).<br \/>\nLoome kaks koera: <code class=\"docutils literal notranslate\"><span class=\"pre\">Clyde<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">Jenkins<\/span><\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    def bark(self):\r\n        print(\"Woof!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(\"Greetings, master\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot!\")\r\n\r\n# Creating the Dog class instance and saving it to the variable &lt;clyde&gt;\r\nclyde = Dog()\r\nclyde.bark()   # --&gt; Woof!\r\nclyde.roll()   # --&gt; *rolling*\r\nclyde.greet()  # --&gt; Greetings, master\r\nclyde.speak()  # --&gt; I cannot!\r\n\r\n# Creating another Dog instance\r\njenkins = Dog()\r\njenkins.bark()  # --&gt; Woof!\r\njenkins.roll()  # --&gt; *rolling*\r\n# .. And other methods\r\n# .. Infinite objects can be created this way, all implementing the same methods defined in our class\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Tuleb v\u00e4lja, et vaatamata sellele, et <code class=\"docutils literal notranslate\"><span class=\"pre\">clyde<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">jenkins<\/span><\/code> on erinevad koerad, oskavad m\u00f5lemad teha asju,<br \/>\nmida meie definitsiooni j\u00e4rgi oskab iga tavaline koer. Nii, nagu reaalses elus umbes ongi &#8211; n\u00e4iteks iga koer oskab haukuda<br \/>\ns\u00f5ltumata tema liigist.<\/p>\n<p>Klassil v\u00f5ib olla ka <strong>konstruktor<\/strong>, mis kujutab endast erilist, fikseeritud nimega, meetodit klassi sees. See fikseeritud nimi on j\u00e4rgmine:<br \/>\n<strong>__init__()<\/strong>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n    # Class constructor\r\n    def __init__(self):\r\n        # Code here\r\n<\/pre>\n<p>Konstruktor ja selle sees olev kood k\u00e4ivitatakse <strong>vaid isendi (objekti) loomisel<\/strong>. N\u00e4iteks tahame, et klassi <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code><br \/>\nisendi loomisel oleks igale klassi objektile antud oma nimi. Teeme nii, et meie konstruktor v\u00f5taks sisse teise argumendi,<br \/>\n<code class=\"docutils literal notranslate\"><span class=\"pre\">name<\/span><\/code>, ja salvestaks selle uue muutuja <code class=\"docutils literal notranslate\"><span class=\"pre\">self.name<\/span><\/code> sisse.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    # Class constructor\r\n    def __init__(self, name):\r\n        self.name = name\r\n\r\n    def bark(self):\r\n        print(\"Woof!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(\"Greetings, master\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot!\")\r\n\r\n    # Returns the current dog's name\r\n    def get_name(self):\r\n        return self.name\r\n\r\n    # Returns the reference to the current dog instance\r\n    def get_this_dog(self):\r\n        return self\r\n\r\n# Creating the Dog class instance and giving it name\r\ndog1 = Dog(\"Clyde\")\r\ndog1.bark()  # --&gt; Woof!\r\ndog1.roll()  # --&gt; *rolling*\r\ndog1.greet() # --&gt; Greetings, master\r\ndog1.speak() # --&gt; I cannot!\r\nprint(dog1.get_name())  # --&gt; Clyde\r\nprint(dog1.get_this_dog())  # --&gt; (Example) &lt;__main__.Dog object at 0x0119D710&gt;\r\nprint(dog1)  # --&gt; (Example) &lt;__main__.Dog object at 0x0119D710&gt;\r\n\r\n# Creating some more Dog instances\r\ndog2 = Dog(\"Jenkins\")\r\ndog2.bark() # --&gt; Woof!\r\ndog2.roll()  # --&gt; *rolling*\r\ndog2.greet() # --&gt; Greetings, master\r\ndog2.speak() # --&gt; I cannot!\r\nprint(dog2.get_name())  # --&gt; Jenkins\r\nprint(dog2.get_this_dog())  # --&gt; (Example) &lt;__main__.Dog object at 0x0143D710&gt;\r\nprint(dog2)  # --&gt; (Example) &lt;__main__.Dog object at 0x0143D710&gt;\r\n\r\ndog3 = Dog(\"Robbie\")\r\nprint(dog3.get_name())  # --&gt; Robbie\r\nprint(dog3.get_this_dog())  # --&gt; (Example) &lt;__main__.Dog object at 0x01CED710&gt;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Seega, vaatamata sellele, et iga koer oskab haukuda, veereda ja tervitada, on k\u00f5ik koerad erinevad objektid, nagu<br \/>\nreaalelus ongi. Muutuja <code class=\"docutils literal notranslate\"><span class=\"pre\">self<\/span><\/code> iseloomustab antud juhul just seda konkreetset koera, kelle objekt on loodud,<br \/>\n<code class=\"docutils literal notranslate\"><span class=\"pre\">self<\/span><\/code> on viide sellele objektile. Seda on n\u00e4ha, kui printida v\u00e4lja meie <code class=\"docutils literal notranslate\"><span class=\"pre\">Dog<\/span><\/code> klassil olev meetod <code class=\"docutils literal notranslate\"><span class=\"pre\">get_this_dog<\/span><\/code><br \/>\nv\u00f5i kui lihtsalt \u00fcritada v\u00e4lja printida objekti ennast, nagu on \u00fcleval tehtud.<br \/>\nNagu n\u00e4ha, on erinevatel objektidel erinev viide, mis t\u00e4hendabki, et n\u00e4iteks Jenkins ja Clyde ei ole \u00fcks ja sama<br \/>\nkoer, vaid kaks erinevat.<br \/>\nKui meie loome muutuja, pannes <code class=\"docutils literal notranslate\"><span class=\"pre\">self<\/span><\/code> juurde prefiksina, nagu tegime <code class=\"docutils literal notranslate\"><span class=\"pre\">self.name<\/span><\/code> korral, siis saame nn<br \/>\n<strong>isendimuutuja<\/strong>, mis on n\u00e4htav igale klassi meetodile:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    # Class constructor\r\n    def __init__(self, name):\r\n        # Instance variable\r\n        self.name = name\r\n\r\n    def bark(self):\r\n        print(self.name + \" says: Woof!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(self.name + \" greets you!\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot\")\r\n\r\n    # Returns the current dog's name\r\n    def get_name(self):\r\n        return self.name\r\n\r\n    # Returns the current dog instance\r\n    def get_this_dog(self):\r\n        return self\r\n\r\ndog1 = Dog(\"Clyde\")\r\ndog1.bark()  # --&gt; Clyde says: Woof!\r\ndog1.greet()  # --&gt; Clyde greets you!\r\nprint(dog1.get_name())  # --&gt; Clyde\r\nprint(dog1)  # --&gt; Reference\r\n\r\ndog2 = Dog(\"Jenkins\")\r\ndog2.bark() # --&gt; Jenkins says: Woof!\r\ndog2.greet() # --&gt; Jenkins greets you!\r\nprint(dog2.get_name())  # --&gt; Jenkins\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Klassil v\u00f5ib olla ka <strong>klassimuutuja<\/strong>, mis on samal moel n\u00e4htav igale klassi meetodile:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Dog:\r\n\r\n    # Class variable\r\n    name = \"Some name\"\r\n\r\n    # Class constructor\r\n    def __init__(self, new_name):\r\n        # Assign class variable to new value\r\n        Dog.name = new_name\r\n\r\n    def bark(self):\r\n        print(Dog.name + \" says: Woof!\")\r\n\r\n    def roll(self):\r\n        print(\"*rolling*\")\r\n\r\n    def greet(self):\r\n        print(Dog.name + \" greets you!\")\r\n\r\n    def speak(self):\r\n        print(\"I cannot\")\r\n\r\n    # Returns the current dog's name\r\n    def get_name(self):\r\n        return Dog.name\r\n\r\n# We do not need to create an object to access the class variable\r\nprint(Dog.name)  # --&gt; Some name\r\n\r\ndog1 = Dog(\"Clyde\")\r\ndog1.bark()  # --&gt; Clyde says: Woof!\r\ndog1.greet()  # --&gt; Clyde greets you!\r\nprint(dog1.get_name())  # --&gt; Clyde\r\nprint(Dog.name)  # --&gt; Clyde\r\n\r\ndog2 = Dog(\"Jenkins\")\r\ndog2.bark() # --&gt; Jenkins says: Woof!\r\ndog2.greet() # --&gt; Jenkins greets you!\r\nprint(dog2.get_name())  # --&gt; Jenkins\r\nprint(Dog.name)  # --&gt; Jenkins\r\n\r\n# Assign new value to the variable name\r\nDog.name = \"Some random dog name\"\r\nprint(Dog.name)  # --&gt; Some random dog name\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Isendimuutuja<\/strong> ja <strong>klassimuutuja<\/strong> erinevad teineteisest selle poolest, et <strong>klassimuutuja<\/strong> eksisteerib, on<br \/>\nk\u00e4ttesaadav ja muudetav ilma objekti loomiseta, kuid samal ajal <strong>isendimuutuja<\/strong> eksisteerib ainult koos oma objektiga.<\/p>\n<p>Veel m\u00f5ni lihtne n\u00e4ide. Oletame, et me tahame koostada klassi, mis kirjeldaks tavalist tudengit. Igal tudengil<br \/>\non olemas nimi ja kool, kus ta \u00f5pib. Samas on suurem osa tudengeid laisad, aga mitte k\u00f5ik. Ehk igal tudengil<br \/>\non kolm parameetrit: nimi, kool ja laiskus, mis on vaikimisi t\u00f5ene.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Student:\r\n    \"\"\"Student class.\"\"\"\r\n\r\n    def __init__(self, name, college, is_lazy=True):\r\n        \"\"\"\r\n        Class constructor.\r\n\r\n        :param name: student name\r\n        :param college: student college\r\n        :param is_lazy: is student lazy? (by default yes)\r\n        \"\"\"\r\n        self.name = name\r\n        self.college = college\r\n        self.is_lazy = is_lazy\r\n<\/pre>\n<p>Tudengitel on alati mingi kodut\u00f6\u00f6. Eeldame, et tudeng saab teha homset kodut\u00f6\u00f6d ainult siis, kui ta ei ole laisk.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">def is_homework_done(self):\r\n    \"\"\"\r\n    Did the student do the homework for tomorrow?\r\n\r\n    :return: string\r\n    \"\"\"\r\n    if self.is_lazy:\r\n        return \"Homework? Pff, I have TV shows to watch.\"\r\n\r\n    return \"Homework is done!\"\r\n<\/pre>\n<p>Lisaks sellele eeldame, et iga tudeng saab oma kooli vahetada.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">def change_college(self, college):\r\n    \"\"\"\r\n    Change the college student attends.\r\n\r\n    :param college:\r\n    :return none\r\n    \"\"\"\r\n    print(\"Student {} leaves the {} and starts studying in {}\".format(self.name, self.college, college))\r\n    self.college = college<\/pre>\n<p>Ja samal moel saab tudeng m\u00f5istuse p\u00e4he v\u00f5tta ja enam mitte laisk olla (v\u00f5i vastupidi):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">def change_laziness(self):\r\n    \"\"\"\r\n    Is the student still lazy\/not lazy?\r\n\r\n    :return: none\r\n    \"\"\"\r\n    self.is_lazy = not self.is_lazy<\/pre>\n<p>Siis, pannes k\u00f5ik kokku, saame:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Student:\r\n    \"\"\"Student class.\"\"\"\r\n\r\n    def __init__(self, name, college, is_lazy=True):\r\n        \"\"\"\r\n        Class constructor.\r\n\r\n        :param name: student name\r\n        :param college: student college\r\n        :param is_lazy: is student lazy? (by default - yes)\r\n        \"\"\"\r\n        self.name = name\r\n        self.college = college\r\n        self.is_lazy = is_lazy\r\n\r\n    def is_homework_done(self):\r\n        \"\"\"\r\n        Did the student do the homework for tomorrow?\r\n\r\n        :return: string\r\n        \"\"\"\r\n        if self.is_lazy:\r\n            return \"Homework? Pff, I have TV shows to watch.\"\r\n\r\n        return \"Homework is done!\"\r\n\r\n    def get_college(self):\r\n        \"\"\"\r\n        Get the college student attends.\r\n\r\n        :return: college\r\n        \"\"\"\r\n        return \"{} studies in {}\".format(self.name, self.college)\r\n\r\n    def change_college(self, college):\r\n        \"\"\"\r\n        Change the college students attends.\r\n\r\n        :param college:\r\n        :return none\r\n        \"\"\"\r\n        print(\"Student {} leaves the {} and starts studying in {}\".format(self.name, self.college, college))\r\n        self.college = college\r\n\r\n    def get_name(self):\r\n        \"\"\"\r\n        Get the student name.\r\n\r\n        :return: name\r\n        \"\"\"\r\n        return self.name\r\n\r\n    def get_laziness(self):\r\n        \"\"\"\r\n        Is the student lazy?\r\n\r\n        :return: true\/false\r\n        \"\"\"\r\n        return self.is_lazy\r\n\r\n    def change_laziness(self):\r\n        \"\"\"\r\n        Is the student still lazy\/not lazy?\r\n\r\n        :return: none\r\n        \"\"\"\r\n        self.is_lazy = not self.is_lazy\r\n\r\n# Some examples\r\n\r\nst1 = Student(\"Alice\", \"Tallinn University of Technology\")\r\nprint(st1)  # --&gt; (Example) &lt;__main__.Student object at 0x01E3DB30&gt;\r\nprint(st1.get_name())  # --&gt; Alice\r\nprint(st1.get_college())  # --&gt; Tallinn University of Technology\r\nprint(st1.get_laziness())  # --&gt; True\r\nprint(st1.is_homework_done())  # --&gt; Homework? Pff, I have TV shows to watch.\r\nprint()\r\n\r\n# Alice decides she is more into art than computers, so she leaves TUT and starts studying in Estonian Academy of Arts.\r\n# Output: Student Alice leaves the Tallinn University of Technology and starts studying in Estonian Academy of Arts\r\nst1.change_college(\"Estonian Academy of Arts\")\r\nprint(st1.get_college())  # --&gt; Estonian Academy of Arts\r\n# She is still lazy though\r\nprint(st1.get_laziness())  # --&gt; True\r\nprint()\r\n\r\nst2 = Student(\"Mary\", \"Massachusetts Institute of Technology\", False)\r\nprint(st2.get_name())  # --&gt; Mary\r\nprint(st2.get_college())  # --&gt; Massachusetts Institute of Technology\r\nprint(st2.get_laziness())  # --&gt; False\r\nprint(st2.is_homework_done())  # --&gt; Homework is done!\r\n# It is weekend now, so Mary can be a bit lazier than usual\r\nst2.change_laziness()\r\nprint(st2.is_homework_done())  # --&gt; Homework? Pff, I have TV shows to watch.<\/pre>\n<p>Vaatleme lisaks \u00fcht sisseehitatud meetodit, mis teeb meie elu veidi lihtsamaks. Meetodi nimi on <code class=\"docutils literal notranslate\"><span class=\"pre\">__str__<\/span><\/code>. Meetod k\u00e4ivitub<br \/>\nsiis, kui me proovime objekti v\u00e4lja printida ja tagastab meie poolt m\u00e4\u00e4ratud stringi tavalise viite asemel. Vaatame,<br \/>\nkuidas see meetod t\u00f6\u00f6tab <code class=\"docutils literal notranslate\"><span class=\"pre\">Student<\/span><\/code> klassi n\u00e4itel.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">class Student:\r\n    \"\"\"Student class.\"\"\"\r\n\r\n    def __init__(self, name, college, is_lazy=True):\r\n        \"\"\"\r\n        Class constructor.\r\n\r\n        :param name: student name\r\n        :param college: student college\r\n        :param is_lazy: is student lazy? (by default - yes)\r\n        \"\"\"\r\n        self.name = name\r\n        self.college = college\r\n        self.is_lazy = is_lazy\r\n\r\n    def __str__(self):\r\n        \"\"\"\r\n        Returns name of the student when invoked.\r\n\r\n        :return: student name\r\n        \"\"\"\r\n        return self.name\r\n\r\n    # &lt;...Other methods skipped...&gt;\r\n\r\n\r\n# Some examples\r\n\r\nst1 = Student(\"Alice\", \"Tallinn University of Technology\")\r\nprint(st1)  # --&gt; Alice\r\nprint()\r\n\r\nst2 = Student(\"Mary\", \"Massachusetts Institute of Technology\", False)\r\nprint(st2)  # --&gt; Mary\r\n<\/pre>\n<p>Ehk n\u00fc\u00fcd ei ole meil vaja luua eraldi meetodit <code class=\"docutils literal notranslate\"><span class=\"pre\">get_name<\/span><\/code> tudengi nime tagastamiseks, nime on v\u00f5imalik saada lihtsalt<br \/>\nobjekti printimisel. <code class=\"docutils literal notranslate\"><span class=\"pre\">__str__<\/span><\/code> ei pea tagastama ainult nime, antud juhul n\u00e4iteks v\u00f5iks ta tagastada ka kooli, kus tudeng \u00f5pib.<\/p>\n<section id=\"lisalugemist\">\n<h2 id=\"lisalugemist\">Lisalugemist<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#lisalugemist\">\uf0c1<\/a><\/h2>\n<ul class=\"simple\">\n<li>\u00dclevaade koos n\u00e4idetega klasside ja objektide kohta W3Schools <a class=\"reference external\" href=\"https:\/\/www.w3schools.com\/python\/python_classes.asp\">Python Classes and Objects<\/a> peat\u00fckis.<\/li>\n<li>Klasside ja objektide kasutamise p\u00f5him\u00f5tted ja n\u00e4ited GeeksforGeeks <a class=\"reference external\" href=\"https:\/\/www.geeksforgeeks.org\/python-classes-and-objects\/\">Python Classes and Objects<\/a> artiklis.<\/li>\n<\/ul>\n<\/section>\n","protected":false},"author":36,"menu_order":1,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"class_list":["post-928","chapter","type-chapter","status-publish","hentry"],"part":926,"_links":{"self":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/928","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/users\/36"}],"version-history":[{"count":3,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/928\/revisions"}],"predecessor-version":[{"id":932,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/928\/revisions\/932"}],"part":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/parts\/926"}],"metadata":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/928\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/media?parent=928"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapter-type?post=928"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/contributor?post=928"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/license?post=928"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}