Skip to content
Snippets Groups Projects
Commit cec1d985 authored by Rafael László's avatar Rafael László :speech_balloon:
Browse files

fixed classes chapter

parent ec36f7b3
No related branches found
No related tags found
No related merge requests found
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
- [Python osztály](#python-osztály) - Felépítés, - [Python osztály](#python-osztály) - Felépítés,
példák, init és dunder metódusok példák, init és dunder metódusok
- [Láthatóság](#láthatóság) - \_ -al privátnak tekintjük - [Láthatóság](#láthatóság) - \_ -al privátnak tekintjük
- [Öröklés](#öröklés) - Keres a megadott ősosztályokban, - [Öröklés](#öröklés) - `Osztály(Ős1, Ős2, ...)`,
"minden `virtual`" Melyik függvényt hívjam?
- [super](#super) - Függvény keresés egy sorrend
alapján
</Note> </Note>
...@@ -30,6 +32,9 @@ megtanulni a dolgokat_ ...@@ -30,6 +32,9 @@ megtanulni a dolgokat_
- Készíts osztályokat a kutyáknak, macskáknak és a - Készíts osztályokat a kutyáknak, macskáknak és a
medvéknek úgy, hogy ezeknek legyen ősosztálya és medvéknek úgy, hogy ezeknek legyen ősosztálya és
a legtöbb közös tulajdonságot reprezentálja. 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> </Note>
...@@ -168,12 +173,12 @@ Hogy legyen is benne valami: ...@@ -168,12 +173,12 @@ Hogy legyen is benne valami:
Ebből tudunk egy példányt készíteni: Ebből tudunk egy példányt készíteni:
```python ```python
>>> x = Osztalyom() >>> x = Osztalyom() # Példányosítás
>>> x.i >>> x.i
12345 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 Ha saját konstruktort szeretnénk, akkor a beépített
**\_\_init\_\_** függvényt tudjuk felhasználni. **\_\_init\_\_** függvényt tudjuk felhasználni.
...@@ -198,7 +203,7 @@ hívják_ ...@@ -198,7 +203,7 @@ hívják_
``` ```
Egy érdekes különbség C-től, hogy a változóinkat 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. vesszük fel őket.
Ha ezt nem így tennénk, akkor valójában egy statikus Ha ezt nem így tennénk, akkor valójában egy statikus
minden objektum közt megosztott változót készítenénk. minden objektum közt megosztott változót készítenénk.
...@@ -263,9 +268,9 @@ class Dog: ...@@ -263,9 +268,9 @@ class Dog:
Erre a magyarázat, hogy ezekre az objektumokra csak mutatók Erre a magyarázat, hogy ezekre az objektumokra csak mutatók
készülnek. készülnek.
Tehát mikor mi definiáltuk az osztályunk akkor készítettünk 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. 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 akkor ugyanazokat a mutató értékeket kapták az egyes
leszármazottak. leszármazottak.
...@@ -294,31 +299,210 @@ class Lathatosag: ...@@ -294,31 +299,210 @@ class Lathatosag:
## Öröklés ## Öröklés
Talán az egyik legbonyolultabbnak ható témakör, Mikor egy osztályból leöröklünk, akkor a gyerekosztály
viszont Pythonban hidd el, hogy nagyon egyszerűen megjegyzi az ősét és később tudunk rá hivatkozni.
működik. 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 ```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
``` ```
Ilyenkor az osztályunk elmenti az összes ősosztályát, Akár több osztályt is megadhatunk ősosztálynak.
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`.
Ha szeretnénk az ősosztály konstruktorát meghívni, akkor Tegyünk bele pár konstruktort
a `super` kulcsszót tudjuk használni.
```python ```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
```
### super
Másik megoldás, hogy használjuk a beépített `super` függvényt.
```python
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self): def __init__(self):
super().__init__() 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 A `super` függvény ilyenkor egy úgynevezett
meg fogja hívni az `__init__` függvényt. 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>
<?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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment