Skip to content

Commit 2b036ed

Browse files
committed
Reword/clarify the info on classes
1 parent a37376e commit 2b036ed

2 files changed

Lines changed: 74 additions & 109 deletions

File tree

lessons/beginners/class/index.md

Lines changed: 63 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Objekty spojují data a funkčnost dohromady.
3232
> Funkce `len` ale funguje i na
3333
> objektech, které s řetězci nemají nic společného.
3434
35+
3536
# Třídy
3637

3738
Data každého objektu jsou specifická pro konkrétní
@@ -57,8 +58,8 @@ Tohle společné chování určuje
5758
*typ* (angl. *type*) neboli *třída* (angl. *class*) daného objektu.
5859

5960
> [note]
60-
> V historických verzích Pythonu byl rozdíl mezi „typem“
61-
> a „třídou“, ale dnes už jsou to synonyma.
61+
> V jiných jazycích než Python 3 můžou slova „typ“ a „třída“ označovat různé
62+
> věci. Pro nás to budou synonyma.
6263
6364
Typ objektu umí zjistit funkce `type`:
6465

@@ -75,9 +76,14 @@ Typ objektu umí zjistit funkce `type`:
7576
<class '_io.TextIOWrapper'>
7677
```
7778

78-
Takže `type` vrací nějaké třídy.
79-
A co je to třída? Popis, jak se chovají všechny objekty
80-
daného typu.
79+
A co je to třída? Třída je *popis*, jak se všechny objekty
80+
daného typu chovají.
81+
82+
Nepříklad `<class 'int'>` obsahuje všechno, co je společné všem celým číslům:
83+
že (a jak) se dají sčítat, jak takové číslo převést na řetězec, a tak dále.
84+
85+
86+
## Tvoření objektů třídy
8187

8288
Většinu tříd jde navíc v Pythonu zavolat, jako by
8389
to byly funkce, a vytvořit tak nový objekt dané třídy:
@@ -95,7 +101,7 @@ Chová se to stejně jako funkce `str`! Není to podivné?
95101
Tady se musím omluvit:
96102
[materiály k funkcím](../functions/)
97103
tak trochu lhaly. Funkce `str`, `int`, `float` apod. totiž vůbec
98-
nejsou funkce – jsou to právě třídy.
104+
nejsou funkce – jsou to právě třídy:
99105

100106
```pycon
101107
>>> str
@@ -108,8 +114,7 @@ True
108114

109115
Ale dají se, podobně jako funkce, zavolat.
110116
Třída tedy většinou obsahuje nejen „popis“, jak se
111-
objekty daného typu budou chovat, ale umí i objekty
112-
daného typu vytvořit.
117+
její objekty budou chovat, ale „umí“ takové objekty i vytvořit.
113118

114119
## Vlastní třídy
115120

@@ -149,7 +154,7 @@ aby se nepletly s „normálními“ hodnotami.
149154
150155
V těle třídy můžeš definovat metody, které vypadají
151156
úplně jako funkce – jen mají první argument `self`.
152-
Ten si ale vysvětlíme později – zamňoukání má přednost:
157+
Ten si ale vysvětlíme později – napřed zkus zamňoukat:
153158

154159
```python
155160
# Vytvoření konkrétního objektu
@@ -161,22 +166,28 @@ kotatko.zamnoukej()
161166

162167
V tomhle příkladu si dej pozor na velikost písmen:
163168
`Kotatko` (s velkým K) je třída – popis, jak
164-
se koťátka chovají. `kotatko` (s malým k)
169+
se koťátka chovají.
170+
`kotatko` (s malým k)
165171
je konkrétní objekt (angl. *instance*) té třídy:
166172
hodnota, která reprezentuje kotě.
167-
Onen konkrétní objekt vytvoříme zavoláním třídy,
168-
stejně jako zavoláním `str()` se dá vytvořit
169-
konkrétní řetězec.
173+
174+
Když definuješ třídu (pomocí bloku `class`), neznamená to, že v tvém
175+
programu je nějaké koťátko.
176+
Třída je jako recept nebo manuál: když si koupíš kuchařku, teoreticky víš
177+
jak upéct dort, jak bude takový dort vypadat a že se dá sníst.
178+
Ale neznamená to ještě, že máš samotný dort!
179+
180+
Konkrétní objekt vytvoříš až zavoláním třídy.
181+
Stejně jako zavoláním `str()` se dá vytvořit konkrétní řetězec,
182+
volání `Kotatko()` vytvoří nový objekt tvé třídy, který už můžeš použít.
170183

171184
Mňau!
172185

173186
## Atributy
174187

175-
Objekty vytvořené z „vlastních“ tříd mají jednu
176-
vlastnost, kterou třídy jako `str`
188+
Objekty vytvořené z „vlastních“ tříd mají funkčnost, kterou třídy jako `str`
177189
nedovolují: možnost si definovat vlastní
178-
*atributy* – informace, které se uloží k danému
179-
objektu.
190+
*atributy* – informace, které se uloží k danému objektu.
180191
Atributy se označují tak, že mezi hodnotu a jméno
181192
jejího atributu napíšeš tečku:
182193

@@ -193,9 +204,9 @@ print(micka.jmeno)
193204

194205
Na začátku jsme si řekl{{gnd('i', 'y', both='i')}}, že objekty spojují chování
195206
a data.
196-
Chování je definováno ve třídě, data se schovávají
197-
právě v atributech jednotlivých objektů.
198-
Podle atributů jako jméno můžeš jednotlivá koťátka
207+
Chování je definováno ve třídě; data se schovávají
208+
právě v atributech jednotlivých objektů.
209+
Podle atributů jako `jmeno` pak můžeš jednotlivá koťátka
199210
rozlišit.
200211

201212
> [note]
@@ -213,13 +224,12 @@ rozlišit.
213224
214225
## Parametr `self`
215226
216-
A teď se na chvíli vrátíme k metodám,
217-
konkrétně k parametru `self`.
227+
Teď se na chvíli vraťme k metodám. Konkrétně k parametru `self`.
218228
219229
Každá metoda má přístup ke konkrétnímu objektu, na
220230
kterém pracuje, právě přes argument `self`.
221-
Teď, když máš koťátka pojmenovaná,
222-
můžeš pomocí `self` rozjet dialog:
231+
Teď, když máš koťátka pojmenovaná, můžeš v metodě `zamnoukej` použít `self`
232+
a dostat se tak ke jménu daného koťátka:
223233
224234
```python
225235
class Kotatko:
@@ -236,23 +246,18 @@ mourek.zamnoukej()
236246
micka.zamnoukej()
237247
```
238248
239-
Co se stalo? Výraz `mourek.zamnoukej` udělá *metodu*, která, když ji zavoláš,
240-
předá objekt `mourek` jako první argument
241-
funkce `zamnoukej`.
249+
Co se stalo? Výraz `mourek.zamnoukej` udělá *metodu*.
250+
Když ji pak zavoláš (`mourek.zamnoukej()`),
251+
objekt `mourek` se předá funkci `zamnoukej` jako první argument, `self` .
242252

243253
> [note]
244-
> Tohle je to, čím se *metoda* liší od normální *funkce*:
245-
> metoda si „pamatuje“ objekt, na kterém pracuje.
254+
> Onen první argument metody můžešw teoreticky pojmenovat i jinak než `self`,
255+
> ale když to uděláš, ostatní programátoři se na tebe budou koukat hodně divně.
246256
247-
A takový první argument, který obsahuje konkrétní
248-
objekt právě definované třídy, se tradičně pojmenovává `self`.
249-
(Když ho pojmenuješ jinak, ostatní programátoři se na tebe budou koukat hodně
250-
divně.)
251257

252-
253-
A může taková metoda brát víc než jeden argument?
258+
Může taková metoda brát víc než jeden argument?
254259
Může – `self` se doplní na první místo,
255-
a zbytek argumentů se vezme z volání metody.
260+
zbytek argumentů se vezme z volání metody.
256261
Třeba:
257262

258263
```python
@@ -270,26 +275,32 @@ mourek.snez('ryba')
270275

271276
## Metoda `__init__`
272277

273-
A když jsme u argumentů, je ještě jedno místo,
274-
kde můžeš třídě poslat argumenty: když vytváříš
275-
nový objekt (voláním třídy).
276-
Dá se tak hezky vyřešit problém, který možná vidíš
277-
v předchozím kódu: aktuálně každé koťátko potřebuje,
278-
aby se mu po vytvoření nastavilo jméno, jinak
279-
metoda `zamnoukej` nebude fungovat.
280-
Třída se ale dá udělat i tak, že půjde jméno nastavit
281-
už při vytváření, takhle:
278+
Co se stane, když koťátku zapomeneš nastavit jméno?
279+
Metoda `zamnoukej` přestane fungovat:
280+
281+
```pycon
282+
>>> micka = Kotatko()
283+
>>> micka.snez('ryba')
284+
Traceback (most recent call last):
285+
File "<zvirata.py>", line 5, in snez
286+
AttributeError: 'Kotatko' object has no attribute 'jmeno'
287+
```
288+
289+
Bylo by dobré zařídit, aby každé kotě muselo být pojmenované.
290+
Jméno potřebujeme předat už při vytváření kotěte, nějak takhle:
282291

283292
```python
284293
mourek = Kotatko(jmeno='Mourek')
285294
```
286295

287-
Na tohle používá Python metodu,
296+
To ale zatím nefunguje; musíme na to třídu `Kotatko` připravit.
297+
298+
Použijeme na to speciální metodu,
288299
která se jmenuje `__init__` (dvě podtržítka,
289300
`init`, dvě podtržítka).
290301
To „opodtržítkování“ znamená, že tohle jméno je nějakým způsobem speciální.
291-
Metoda `__init__` se totiž zavolá
292-
automaticky, když se vytvoří nový objekt.
302+
Metodu `__init__` totiž Python zavolá
303+
automaticky, když vytvoří nový objekt.
293304
Dá se tedy napsat:
294305

295306
```python
@@ -307,11 +318,11 @@ mourek = Kotatko('Mourek')
307318
mourek.zamnoukej()
308319
```
309320

310-
A teď už není možnost, jak vytvořit koťátko bez jména,
311-
takže `zamnoukej` bude vždycky fungovat.
321+
A teď už není možnost, jak vytvořit koťátko beze jména.
322+
Metoda `zamnoukej` bude vždycky fungovat.
312323

313-
Podobných „opodtržítkovaných“ metod je víc,
314-
třeba `__str__` se volá, když je potřeba
324+
Podobných „opodtržítkovaných“ (speciálních) metod je víc.
325+
Třeba `__str__` se volá, když je potřeba
315326
převést objekt na řetězec:
316327

317328
```python
@@ -332,48 +343,6 @@ mourek = Kotatko('Mourek')
332343
print(mourek)
333344
```
334345

335-
## Cvičení: Kočka
336-
337-
Teď, když už umíš dělat koťátka, zkus vytvořit třídu pro kočku.
338-
339-
- Kočka umí mňoukat metodou `zamnoukej`.
340-
- Kočka má na začátku (při vytvoření) 9 životů
341-
(nemůže mít nikdy víc než 9 nebo míň než 0!).
342-
- Kočka umí říct, jestli je živá (nemá 0 životů), metodou `je_ziva`.
343-
- Kočka může ztratit život metodou `uber_zivot`.
344-
- Kočku můžeš nakrmit metodou `snez`, která bere 1 argument -
345-
nějaké konkrétní jídlo (řetězec). Pokud je toto jídlo `"ryba"`, kočce se obnoví
346-
jeden život (pokud teda už není mrtvá, nebo nemá maximální počet životů).
347-
348-
{% filter solution %}
349-
```python
350-
class Kocka:
351-
def __init__(self): # Init funkce nemusi brat jako parametr
352-
self.pocet_zivotu = 9 # pocet zivotu, ten je pokazde 9.
353-
354-
def zamnoukej(self):
355-
print("Mnau, mnau, mnauuu!")
356-
357-
def je_ziva(self):
358-
return self.pocet_zivotu > 0
359-
360-
def uber_zivot(self):
361-
if not self.je_ziva():
362-
print("Nemuzes zabit uz mrtvou kocku!")
363-
else:
364-
self.pocet_zivotu -= 1
365-
366-
def snez(self, jidlo):
367-
if not self.je_ziva():
368-
print("Je zbytecne krmit mrtvou kocku!")
369-
return
370-
if jidlo == "ryba" and self.pocet_zivotu < 9:
371-
self.pocet_zivotu += 1
372-
print("Kocka spapala rybu a obnovil se ji jeden zivot.")
373-
else:
374-
print("Kocka se krmi.")
375-
```
376-
{% endfilter %}
377346

378347
A to je o samotných třídách zatím vše.
379348
[Příště](../inheritance/) si něco řekneme o dědičnosti.

lessons/beginners/inheritance/index.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,13 @@ Kdybys měla napsat i třídu pro kuřátka, kůzlátka,
3434
slůňátka a háďátka, bez Ctrl+C by to bylo docela nudné.
3535
A protože jsou programátoři líní psát stejný kód
3636
několikrát (a hlavně ho potom udržovat), vymysleli
37-
mechanismus, jak se toho vyvarovat. Jak?
37+
mechanismus, jak se toho vyvarovat.
3838

3939
Koťátka i štěňátka jsou zvířátka.
4040
Můžeš si vytvořit třídu společnou pro všechna
4141
zvířátka a do ní napsat všechno, co je společné.
42-
Ve třídách pro jednotlivé druhy zvířat pak zbude jen
43-
to, co se liší.
44-
V Pythonu se to dělá takto:
42+
Ve třídách pro jednotlivé druhy zvířat pak zbude jen to, co se liší.
43+
V Pythonu se to dělá takto:
4544

4645
```python
4746
class Zviratko:
@@ -89,8 +88,7 @@ Když potom Python hledá nějakou metodu
8988
a nenajde ji přímo ve třídě daného objektu (u nás
9089
`Kotatko`), podívá se do nadtřídy.
9190
Takže všechno, co je definované pro
92-
`Zviratko`, platí i pro koťátka.
93-
Pokud to tedy výslovně nezměníš.
91+
`Zviratko`, platí i pro koťátka – dokud to výslovně nezměníš.
9492

9593

9694
## Přepisování metod a `super()`
@@ -160,15 +158,15 @@ Dokonce se to dělá poměrně často!
160158

161159
Programátoři nezavedli dědičnost jen proto, že jsou
162160
líní a nechtějí psát dvakrát stejný kód.
163-
To je sice dobrý důvod, ale nadtřídy mají ještě jednu
164-
důležitou vlastnost: když víme, že každé
161+
To je sice dobrý důvod, ale nadtřídy mají jednu
162+
důležitější vlastnost. Když víš, že každé
165163
`Kotatko` nebo `Stenatko`
166164
nebo jakákoli jiná podtřída je zvířátko,
167-
můžeme si udělat seznam zvířátek s tím,
168-
že nám pak bude jedno, jaká přesně zvířátka to jsou:
165+
můžeš si udělat seznam zvířátek s tím,
166+
že pak bude jedno, jaká přesně zvířátka to jsou:
169167

170-
{# XXX: last 4 lines are new and should be highlighted #}
171168
```python
169+
{# XXX: perhaps put these definitions back, but highlight the 4 lines below?
172170
class Zviratko:
173171
def __init__(self, jmeno):
174172
self.jmeno = jmeno
@@ -185,7 +183,7 @@ class Kotatko(Zviratko):
185183
class Stenatko(Zviratko):
186184
def zastekej(self):
187185
print("{}: Haf!".format(self.jmeno))
188-
186+
#}
189187
zviratka = [Kotatko('Micka'), Stenatko('Azorek')]
190188

191189
for zviratko in zviratka:
@@ -210,7 +208,7 @@ protože každé koťátko *je* zvířátko.
210208
> V takovém případě dědičnost nepoužívej.
211209
> I když jak auto tak volant se dají „otočit doprava”,
212210
> u každého to znamená něco jiného – a určitě nejde auto
213-
> použít kdekoli, kde bych chtěl{{a}} použít volant.
211+
> použít kdekoli, kde bys chtěl{{a}} použít volant.
214212
> Takže v tomto případě je lepší si říct „každé auto
215213
> ** volant”, stejně jako „každé kotě
216214
> ** jméno”, udělat dvě nezávislé třídy a napsat něco jako:
@@ -272,5 +270,3 @@ z ní dědit má.
272270

273271
A to je zatím o třídách vše. Už toho víš dost na to,
274272
aby sis napsal{{a}} vlastní zoo :)
275-
276-
Nebo [hru](../../projects/asteroids/)?

0 commit comments

Comments
 (0)