Skip to content
Snippets Groups Projects
Select Git revision
  • 42c4f5e0383a7bb8d30ba318d53b190940791753
  • upstream default protected
  • master
3 results

README.md

Blame
  • 09-objekty.tex 5.82 KiB
    \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{2024}
    \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říšera')
    }{%
    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
    }{%
    Zvire(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.
    
    \end{frame}
    
    % ----------------------------------------------------------------------
    
    \begin{frame}{Další protokoly}
    
    Další protokoly, které může třída implementovat:
    
    \medskip
    
    \begin{itemize}
    \item Konverze na bool, str, int, float
    \item Indexování: čtení/zápis/mazání {\it obj\/}{\bf [...]}, {\bf len(}{\it obj\/}{\bf )}
    \item Přístup k~atributům: čtení/zápis/mazání {\it obj\/}{\bf .klíč}
    \item Volání jako funkce
    \item Iterátor pro {\bf for} {\it x\/} {\bf in} {\it objekt\/}
    \end{itemize}
    
    \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}{Dotazy na typy}
    
    \py{%
    type(k) is Kocka
    }{%
    True
    }
    
    \py{%
    type(k) is Zvire
    }{%
    False
    }
    
    \py{%
    isinstance(k, Kocka)
    }{%
    True
    }
    
    \py{%
    isinstance(k, Zvire)
    }{%
    True
    }
    
    \py{%
    issubclass(Kocka, Zvire)
    }{%
    True
    }
    
    \end{frame}
    
    % ----------------------------------------------------------------------
    
    \begin{frame}{Jak to funguje uvnitř: namespaces a scope}
    
    {\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 (každého zavolání)
    \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}. Tomu se říká {\bf scope.}
    
    \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
    (nebo recyklování existujícího u~neměnných typů).
    
    \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}