Skip to content
Snippets Groups Projects
Commit 1bc9ec1d authored by Martin Mareš's avatar Martin Mareš
Browse files

Objekty

parent 6930ab98
No related branches found
No related tags found
No related merge requests found
\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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment