Commit 1bc9ec1d authored by Mareš Martin's avatar Mareš Martin
Browse files

Objekty

parent 6930ab98
\documentclass{beamer}
\usepackage[utf8]{inputenc}
\usepackage[czech]{babel}
\usepackage{palatino}
\usepackage{verbatim}
\usetheme{Warsaw}
\title{Programování 1: Třídy a objekty}
\author[Martin Mareš]{Martin Mareš\\\texttt{mj@ucw.cz}}
\institute{Katedra Aplikované Matematiky\\MFF UK Praha}
\date{2019}
\begin{document}
\setbeamertemplate{navigation symbols}{}
\setbeamertemplate{footline}{}
\setbeamerfont{title page}{family=\rmfamily}
\shorthandoff{"}
\begin{frame}
\titlepage
\end{frame}
\input ../slidemac.tex
% ----------------------------------------------------------------------
\begin{frame}{Definice třídy}
\verbatiminput{trida_def.py}
~
Definujeme nový typ, který má nějaké {\bf atributy} (vlastnosti)
a~{\bf metody} (funkce, operace).
\end{frame}
% ----------------------------------------------------------------------
\begin{frame}{Objekty}
Vytvoříme nový objekt (automaticky zavolá {\tt \_\_init\_\_}):
\smallskip
\py{%
azor = Zvire("Azor", "Haf!")\\
azor
}{%
<Zvire object at 0x7ffff71ce2b0>
}
\smallskip
Atributy objektu:
\smallskip
\py{%
azor.zvuk
}{%
'Haf!'
}
\py{%
azor.zvuk = "Hafff!"
}{%
}
\smallskip
Metody objektu:
\smallskip
\py{%
azor.slysi\_na('Příšero')
}{%
False
}
\py{%
azor.ozvi\_se()
}{%
Azor říká: Hafff!
}
\end{frame}
% ----------------------------------------------------------------------
\begin{frame}{Identita objektu}
\py{%
jezevcik = Zvire("Špagetka", "haf")\\
bernardyn = Zvire("Bernard", "HAF!!!")\\
maxipes = bernardyn\\
maxipes.jmeno = "Fík"\\
bernardyn.jmeno
}{%
'Fík'
}
\py{%
type(jezevcik)
}{%
<class 'Zvire'>
}
\py{%
id(jezevcik), id(bernardyn), id(maxipes)
}{%
(737339253592, 737339253704, 737339253704)
}
\py{%
bernardyn is maxipes
}{%
True
}
\py{%
bernardyn is jezevcik
}{%
False
}
\end{frame}
% ----------------------------------------------------------------------
\begin{frame}{Protokol pro převod na řetězec}
\verbatiminput{trida_str.py}
\medskip
\py{%
hroch = Zvire("Hippo", "Humpf!")\\
hroch
}{%
Pes(Hippo, Humpf!)
}
\py{%
print(hroch)
}{%
Hippo
}
\end{frame}
% ----------------------------------------------------------------------
\begin{frame}{Protokol pro operátory}
\verbatiminput{trida_op.py}
\medskip
\py{%
hroch1 = Zvire("Hippo", "Humpf!")\\
hroch2 = Zvire("Hippo", "Humpf!")\\
hroch1 is hroch2
}{%
False
}
\py{%
hroch1 == hroch2
}{%
True
}
\smallskip
Podobně jde předefinovat všechny operátory včetně {\bf []} a {\bf .}
\end{frame}
% ----------------------------------------------------------------------
\begin{frame}{Dokumentační komentáře}
\verbatiminput{trida_doc.py}
\py{%
help(Zvire)
}{%
}
\py{%
z = Zvire("Lenochod", "Zzz...")\\
help(z.slysi\_na)
}{%
}
\end{frame}
% ----------------------------------------------------------------------
\begin{frame}{Dědičnost}
\verbatiminput{trida_dedicnost.py}
\py{%
k = Kocka("Příšerka", "Mňauuu")\\
k.slysi\_na("Příserka") \cmt{(speciální kočičí verze)}
}{%
False
}
\py{%
k.ozvi\_se() \cmt{(původní zvířecí metoda)}
}{%
Příšerka říká: Mňauuu
}
\end{frame}
% ----------------------------------------------------------------------
\begin{frame}{Jak to funguje uvnitř}
{\bf Prostory jmen (namespaces):}
\medskip
\begin{itemize}
\item Zabudované funkce (třeba {\tt print})
\item Globální jména (proměnné, funkce)
\item Lokální jména uvnitř funkce
\item Jména definovaná v~třídě
\item Jména definovaná v~objektu
\end{itemize}
\medskip
Obyčejné jméno se hledá ve všech prostorech, které jsou na daném
místě v~programu \uv{vidět}.
\medskip
{\tt objekt.jméno} se hledá:
\medskip
\begin{itemize}
\item V~prostoru atributů objektu
\item V~prostoru příslušné třídy
\item V~prostorech všech nadřazených tříd
\item Pozor, třída může mít více přímých předků!
\end{itemize}
\end{frame}
% ----------------------------------------------------------------------
\begin{frame}{Jak to funguje uvnitř: zabudované typy}
{\bf Zabudované typy jako int, str apod.} jsou rovněž třídy.
Volání {\tt int()} nebo {\tt int("1")} je prostě vytvoření objektu dané třídy.
\medskip
{\bf Třída je také objekt:}
\medskip
\begin{itemize}
\item Lze psát třeba {\tt Zvire.slysi\_na}.
\item Uvnitř třídy můžeme přiřazovat do proměnných, ty jsou vidět jako
atributy třídy.
\item Vnitřek definice {\tt class} je ve skutečnosti normální program,
který se provádí uvnitř prostoru jmen třídy.
\end{itemize}
\medskip
{\bf Modul je také objekt:}
\medskip
\begin{itemize}
\item {\tt import math} ho vytvoří
\item {\tt math.random} je formálně přístup k~atributu
\end{itemize}
\medskip
{\bf Volání metody:}
\medskip
\begin{itemize}
\item {\tt alik.ozvi\_se} vytvoří pomocnou funkci, která zavolá
{\tt Zvire.ozvi\_se} a doplní jako první argument {\tt alik}.
\end{itemize}
\end{frame}
% ----------------------------------------------------------------------
\end{document}
SLIDES=09-objekty.pdf
include ../Makerules
class Zvire:
"""Vytvoří zvíře s danými vlastnostmi."""
def __init__(self, jmeno, zvuk):
self.jmeno = jmeno
self.zvuk = zvuk
def slysi_na(self, jmeno):
"""Slyší zvíře na dané jméno?"""
return self.jmeno == jmeno
def ozvi_se(self):
"""Vydá zvuk daného zvířete."""
print(self.jmeno, "říká:", self.zvuk)
def __str__(self):
return self.jmeno
def __repr__(self):
return f"Pes({self.jmeno}, {self.zvuk})"
def __eq__(self, other):
return self.jmeno == other.jmeno and \
self.zvuk == other.zvuk
class Kocka(Zvire):
"""Vytvoří kočku s danými vlastnostmi."""
def __init__(self, jmeno, zvuk):
Zvire.__init__(self, jmeno, zvuk)
self.pocet_zivotu = 9
def slysi_na(self, jmeno):
# Copak kočka slyší na jméno?
return False
class Kocka(Zvire):
def __init__(self, jmeno, zvuk):
Zvire.__init__(self, jmeno, zvuk)
self._pocet_zivotu = 9 # interní
def slysi_na(self, jmeno):
# Copak kočka slyší na jméno?
return False
class Zvire:
def __init__(self, jmeno, zvuk):
self.jmeno = jmeno
self.zvuk = zvuk
def slysi_na(self, jmeno):
return self.jmeno == jmeno
def ozvi_se(self):
print(self.jmeno, "říká:", self.zvuk)
class Zvire:
"""Vytvoří zvíře s danými vlastnostmi."""
def __init__(self, jmeno, zvuk):
self.jmeno = jmeno
self.zvuk = zvuk
def slysi_na(self, jmeno):
"""Slyší zvíře na dané jméno?"""
return self.jmeno == jmeno
class Zvire:
def __init__(self, jmeno, zvuk):
self.jmeno = jmeno
self.zvuk = zvuk
def __eq__(self, other):
return self.jmeno == other.jmeno and \
self.zvuk == other.zvuk
class Zvire:
def __init__(self, jmeno, zvuk):
self.jmeno = jmeno
self.zvuk = zvuk
def __str__(self):
return self.jmeno
def __repr__(self):
return f"Pes({self.jmeno}, {self.zvuk})"
......@@ -5,6 +5,6 @@
- sort(key=...)
- funkce vyšších řádů
- rekurze
- comprehension pro slovníky a množiny
- životnost objektů, destruktory, weak references
- příště u domácích úkolů napsat, jak velké vstupy mají zvládat
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment