From cec1d98510fa8a29b07bca9c491c150a18060928 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafael=20L=C3=A1szl=C3=B3?= <rlacko99@gmail.com>
Date: Wed, 10 Mar 2021 17:26:16 +0100
Subject: [PATCH] fixed classes chapter

---
 guide/07_scope_class.md | 238 +++++++++++++++++++++++++++++++++++-----
 guide/injektalas.svg    |   3 +
 2 files changed, 214 insertions(+), 27 deletions(-)
 create mode 100644 guide/injektalas.svg

diff --git a/guide/07_scope_class.md b/guide/07_scope_class.md
index 9167190..c3625bb 100644
--- a/guide/07_scope_class.md
+++ b/guide/07_scope_class.md
@@ -16,8 +16,10 @@
 - [Python osztály](#python-osztály) - Felépítés,
   példák, init és dunder metódusok
 - [Láthatóság](#láthatóság) - \_ -al privátnak tekintjük
-- [Öröklés](#öröklés) - Keres a megadott ősosztályokban,
-  "minden `virtual`"
+- [Öröklés](#öröklés) - `Osztály(Ős1, Ős2, ...)`,
+  Melyik függvényt hívjam?
+  - [super](#super) - Függvény keresés egy sorrend
+    alapján
 
 </Note>
 
@@ -30,6 +32,9 @@ megtanulni a dolgokat_
 - Készíts osztályokat a kutyáknak, macskáknak és a
   medvéknek úgy, hogy ezeknek legyen ősosztálya és
   a legtöbb közös tulajdonságot reprezentálja.
+- Injektálj be egy osztályt a kutyák és a készített
+  ősosztály közé úgy, hogy minden konstruktor
+  lefusson. (Tipp: super)
 
 </Note>
 
@@ -37,7 +42,7 @@ megtanulni a dolgokat_
 
 Az osztályok egy lehetőséget biztosítanak, hogy
 az adatainkat és a hozzájuk kapcsolódó funkcionalitást
-össze csatoljuk.  
+összecsatoljuk.  
 Osztályainkból különböző objektumokat tudunk létrehozni,
 melyek saját egyedi adatokkal rendelkeznek.  
 Ezek mellett az egyes osztályainknak lehetnek leszármazottaik,
@@ -168,12 +173,12 @@ Hogy legyen is benne valami:
 Ebből tudunk egy példányt készíteni:
 
 ```python
->>> x = Osztalyom()
+>>> x = Osztalyom() # Példányosítás
 >>> x.i
 12345
 ```
 
-Ilyenkor meghívtuk az alapértelmezett konstruktorát.
+Ilyenkor meghívódott az alapértelmezett konstruktora.
 
 Ha saját konstruktort szeretnénk, akkor a beépített
 **\_\_init\_\_** függvényt tudjuk felhasználni.
@@ -198,7 +203,7 @@ hívják_
 ```
 
 Egy érdekes különbség C-től, hogy a változóinkat
-nem definiáljuk kötvetlen, hanem az init metódusában
+nem definiáljuk közvetlen, hanem az init metódusában
 vesszük fel őket.  
 Ha ezt nem így tennénk, akkor valójában egy statikus
 minden objektum közt megosztott változót készítenénk.
@@ -263,9 +268,9 @@ class Dog:
 Erre a magyarázat, hogy ezekre az objektumokra csak mutatók
 készülnek.
 Tehát mikor mi definiáltuk az osztályunk akkor készítettünk
-egy új listát `[]`, majd pedig a trickset rámutattuk a
+egy új listát `[]`, majd pedig a tricks változót rámutattuk a
 listánkra.
-Ezt követően mikor ebből új objektumokat képeztünk,
+Ezt követően mikor ebből új példányokat képeztünk,
 akkor ugyanazokat a mutató értékeket kapták az egyes
 leszármazottak.
 
@@ -294,31 +299,210 @@ class Lathatosag:
 
 ## Öröklés
 
-Talán az egyik legbonyolultabbnak ható témakör,
-viszont Pythonban hidd el, hogy nagyon egyszerűen
-működik.
+Mikor egy osztályból leöröklünk, akkor a gyerekosztály
+megjegyzi az ősét és később tudunk rá hivatkozni.  
+Az egyes függvények és változók elérhetőek
+a leszármazott osztály `self`-jében, viszont hogy
+pontosan melyik ősosztály függvényét hívjuk, ha
+egyezés van köztük az nem egyértelmű elsőre ha
+például több osztályunk is van.
+
+Nézzük is meg!  
+(`Osztálynév(Ősosztály, ...)`)
 
 ```python
-class Osztály(Ősosztály1, Ősosztály2, ...):
-    .
-    .
-    .
+class A:
+  pass
+
+class B(A):
+  pass
+
+b = B() # Példányosítottuk
+print(isinstance(b, A))
+# isinstance metódus ellenőrzi, hogy leszármazottja-e
+# az objektumunk A-nak
+
+# Kimenet:
+# True
+```
+
+Akár több osztályt is megadhatunk ősosztálynak.
+
+Tegyünk bele pár konstruktort
+
+```python
+class A:
+  def __init__(self):
+    print("A")
+
+class B(A):
+  def __init__(self):
+    print("B")
+```
+
+Mit gondolsz, példányosításkor mi fog történni?
+
+```python
+b = B()
+
+# Kimenet:
+# B
+```
+
+Nem futott le az A konstruktora.
+Ezt két féleképp tudjuk megoldani.
+
+```python
+class A:
+  def __init__(self):
+    print("A")
+
+class B(A):
+  def __init__(self):
+    A.__init__(self) # Explicit meghívjuk A konstruktorát
+    print("B")
+
+b = B()
+
+# Kimenet:
+# A
+# B
 ```
 
-Ilyenkor az osztályunk elmenti az összes ősosztályát,
-majd pedig ha hivatkozni próbálunk benne valamire,
-akkor sorban ellenőrzi először az Osztály-ban, majd
-pedig az Ősosztályokban, hogy hol található meg.
-Ha nem található, akkor meg a szokásos hibával tér vissza.  
-Tehát C++-ra gondolva például minden függvényünk `virtual`.
+### super
 
-Ha szeretnénk az ősosztály konstruktorát meghívni, akkor
-a `super` kulcsszót tudjuk használni.
+Másik megoldás, hogy használjuk a beépített `super` függvényt.
 
 ```python
-def __init__(self):
-        super().__init__()
+class A:
+  def __init__(self):
+    print("A")
+
+class B(A):
+  def __init__(self):
+    super().__init__()
+    # ez super(B, self).init() -ként is írhatnánk
+    # alapértelmezetten az üres verzió python 3-ban
+    # (B, self)-re egészül
+    print("B")
+
+b = B()
+
+# Kimenet:
+# A
+# B
 ```
 
-Ha többszörös öröklésünk van, akkor sorban mindre
-meg fogja hívni az `__init__` függvényt.
+A `super` függvény ilyenkor egy úgynevezett
+metódus feloldási sorrendet követve végigjárja
+a megadott osztálytól kezdve az ősosztályokat
+és megkeresi a megfelelő függvényt, majd megáll.  
+Tehát a fenti példánál megtalálta `A`-ban az
+`__init__` függvényt és abbahagyta a keresést,
+majd meghívta a függvényt.
+
+A metódus feloldási sorrendünk ez esetben:
+
+```python
+print(B.__mro__) # Method Resolution Order
+
+# Kimenet:
+# (<class '__main__.B'>,
+# <class '__main__.A'>,
+# <class 'object'>)
+```
+
+Mikor a `super`-t alapértelmezetten `B`-től indítottuk,
+akkor a következő `A` osztályban kereste meg az `__init__`
+függvényt.
+
+_Azt is észrevehetted, hogy alapértelmezetten az osztályaink
+az object osztályból öröklődnek_
+
+Na de miért használjak `super` -t?
+
+```python
+class A(object):
+    def __init__(self):
+        print('A.__init__(self) -t hívtunk')
+
+class B(A):
+    def __init__(self):
+        print('B.__init__(self) -t hívtunk')
+        A.__init__(self) # Nem használtam Super-t
+
+class C(A):
+    def __init__(self):
+        print('C.__init__(self) -t hívtunk')
+        super(C, self).__init__() # Használtam Supert
+```
+
+Ha netán úgy döntenénk, hogy ezekből az osztályokból
+leszeretnénk származni, de úgy, hogy
+A alá még helyezünk egy osztályt, így:
+
+<ImageZoom 
+  src="guide/injektalas.svg" 
+  :border="false" 
+  width="100%"
+/>
+
+```python
+class Injektalt_Osztaly(A):
+    def __init__(self):
+        print('Injektalt_Osztaly.__init__(self) -t hívtunk')
+        super(Injektalt_Osztaly, self).__init__()
+
+class B_bol(B, Injektalt_Osztaly):
+  pass
+
+class C_bol(C, Injektalt_Osztaly):
+  pass
+
+B_bol()
+# Kimenet:
+# B.__init__(self) -t hívtunk
+# A.__init__(self) -t hívtunk
+
+C_bol()
+# Kimenet:
+# C.__init__(self) -t hívtunk
+# Injektalt_Osztaly.__init__(self) -t hívtunk
+# A.__init__(self) -t hívtunk
+```
+
+Miért nem futott le a B_bol esetén?  
+Nézzük meg a metódus feloldási sorrendet
+
+`<class '__main__.B_bol'>,`  
+`<class '__main__.B'>,`  
+`<class '__main__.Injektalt_Osztaly'>,`  
+`<class '__main__.A'>,`  
+`<class 'object'>`
+
+`B_bol` osztály után meghívódott `B` konstruktora,
+mert az alapértelmezett konstruktora `B`-nek meghívja
+a `super()` függvényt.  
+Ezt követően `B`-ben a következő hívás `A`-ra fog
+mutatni.
+Ezt követően pedig a végére érünk és ha hívnánk
+újabb `super`-t, akkor már az object jönne.
+
+Mikor a `C_bol` osztályból indultunk, akkor `C`
+osztályban a `super` függvény lefutott és
+az `Injektalt_Osztaly`-ban megtalálta a függvényünk.
+
+<Note type="tip" label>
+
+<Badge type="tip">Összefoglalva</Badge>  
+Mikör öröklünk és a super függvényunk használjuk,
+akkor felépít egy metódus feloldási sorrendet attól
+függően, hogy hogyan definiáltuk az osztályainkat.
+Ezt követően mikor hívogatjuk a super-eket,
+akkor mindig a sorrendben következő fog jönni, kivéve
+ha átugorjuk, mert statikusan definiáljuk, hogy
+melyik a következő osztály.
+
+A super-el akár más függvényeket is megtudunk így találni.
+
+</Note>
diff --git a/guide/injektalas.svg b/guide/injektalas.svg
new file mode 100644
index 0000000..762c04a
--- /dev/null
+++ b/guide/injektalas.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="571px" height="351px" viewBox="-0.5 -0.5 571 351" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-03-10T15:55:32.730Z&quot; agent=&quot;5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36&quot; etag=&quot;zjmbRn0q47QHrzn2UEQo&quot; version=&quot;14.2.1&quot;&gt;&lt;diagram id=&quot;8qbvYp1L-6Gzw-SXsElt&quot; name=&quot;Page-1&quot;&gt;7ZlBc6IwGIZ/Dcc6JCFgj9a2uz3stjMe2t1LJ4VUaJHYGBX76zdIAgR11LaInfWiyZvkI/neh0jQQv1R+oOTcfiLBTS2oB2kFrq0IHQwlJ+ZsMgFz8W5MORRkEugFAbRO1WirdRpFNCJ0VEwFotobIo+SxLqC0MjnLO52e2ZxeZVx2RIV4SBT+JV9T4KRJirXWyX+k8aDUN9ZWCrlhHRnZUwCUnA5hUJXVmozxkTeWmU9mmc5U7nJR93vaG1mBinidhlwG/nJfzri7uzG+/2Pomc2eDNPVPuzEg8VQu2oBvLeBfPTIaVsxYLlQr3bcp0w9lkaVRPdoBonJaNsjTMvns6jJxPHinXVSqKoJCzaRLQbIq2bJ6HkaCDMfGz1rkESmqhGMWyBorRM8oFTTdmARS5lUxSNqKCL2QXDaQGS/GojZyX5npKCiu+ao0onIZF4DLjsqCSvocBqCEDLo7VABebBgCvZQechhzoH6sD4NgcwE3dA49PLNahnnhpwHH6gj3TFwRb9sVt6s74Xr5Ap+YLatkXryFfbpIX+ipILB5vJ+/C6iOrB+LF9zEK1TY2uMYocH5Ip7prnKoliSZBL3tOlbWnmPmvMhUBmYTLtGV5ke3XUXbVZRJlTT0jA2jmj6aReKiU/2QjOljVLlMdIKssimhykQ/LjggCLWQjQcfGnhbKwcuaMfqO8kjminIl5uujwcpTdc1EmQM25T7dvv0IwodUbLsdVqGomu4qgzmNiYhm5tzWua7C3bFoeUPpHdo2AXPsGjj5mtSo6rN4LZDrbgmUL3olkCSFLCrdxlmHyeYJo/pPCjbOCLKQRywJLxL4cejPDw+9/THo3RrywGkZeXxC/rPI1yd8EOT1ofKgzHcgrmK/K/TYgH4L8C1s587/w/aX4QfawO9b0bfrzopO9O1N37qXiEdJX5W9CorN0+fsSB880bc3feveoB7TT+8XYnTAzanmKsCog92PEeJ0zVhdfFhA1r3gbRwQx0XGmUSdLTZvUrJSP1hUj+fd+lml9eO5d9rT9kdWVst//PLu5d+m6Oof&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="260" y="0" width="70" height="70" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 68px; height: 1px; padding-top: 35px; margin-left: 261px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><font style="font-size: 23px">A</font></div></div></div></foreignObject><text x="295" y="39" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">A</text></switch></g><rect x="500" y="120" width="70" height="70" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 68px; height: 1px; padding-top: 155px; margin-left: 501px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><font style="font-size: 23px">B</font></div></div></div></foreignObject><text x="535" y="159" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">B</text></switch></g><rect x="0" y="120" width="70" height="70" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 68px; height: 1px; padding-top: 155px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><font style="font-size: 23px">C</font></div></div></div></foreignObject><text x="35" y="159" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">C</text></switch></g><rect x="420" y="270" width="70" height="70" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 68px; height: 1px; padding-top: 305px; margin-left: 421px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><font style="font-size: 23px">B_bol<br /></font></div></div></div></foreignObject><text x="455" y="309" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">B_bol&#xa;</text></switch></g><rect x="90" y="280" width="70" height="70" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 68px; height: 1px; padding-top: 315px; margin-left: 91px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><font style="font-size: 23px">C_bol<br /></font></div></div></div></foreignObject><text x="125" y="319" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">C_bol&#xa;</text></switch></g><rect x="200" y="180" width="190" height="70" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 188px; height: 1px; padding-top: 215px; margin-left: 201px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><font style="font-size: 23px">Injektalt_Osztály<br /></font></div></div></div></foreignObject><text x="295" y="219" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Injektalt_Osztály&#xa;</text></switch></g><path d="M 160 315 L 210.3 302.43 Q 220 300 226.65 292.53 L 251.6 264.53" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 260.25 254.82 L 256.45 268.86 L 246.75 260.21 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 420 305 L 359.97 300.71 Q 350 300 344.08 291.94 L 322.36 262.36" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 314.66 251.88 L 327.6 258.51 L 317.12 266.21 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 107.5 280 L 43.86 200.99" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 35.7 190.87 L 48.92 196.92 L 38.79 205.07 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 455 270 L 525.02 199.98" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 534.21 190.79 L 529.61 204.58 L 520.42 195.39 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 35 120 L 246.79 39.99" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 258.95 35.4 L 249.09 46.07 L 244.5 33.91 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 517.5 120 L 342.86 40.83" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 331.02 35.46 L 345.54 34.91 L 340.17 46.75 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 287.97 180.98 L 287.15 88.11" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 287.03 75.11 L 293.65 88.05 L 280.65 88.17 Z" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
\ No newline at end of file
-- 
GitLab