\chapterimage{orque}
\chaptertext{}

\chapter{POO for dummies}


\section{Syntaxe?}

Vous  vous   êtes  sûrement  demandé   pourquoi  les  appels   de  \og
fonctions\fg{} n'ont pas toujours la même syntaxe:

\begin{pythoncode}
In [67]: e = [1,2]

In [68]: len(e)
Out[68]: 2

In [69]: e.len
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-69-8a0fbf71e19e> in <module>()
----> 1 e.len

AttributeError: 'list' object has no attribute 'len'

In [70]: append(e,3)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-70-18248a9bc3f7> in <module>()
----> 1 append(e,3)

NameError: name 'append' is not defined

In [71]: e.append(3)

In [72]: e
Out[72]: [1, 2, 3]
\end{pythoncode}

Même les nombres ont ce genre de \og fonctions\fg{} bizarres qui suivent un
point:

\begin{pythoncode}
In [73]: 1.2.is_integer()
Out[73]: False

In [74]: 1.0.is_integer()
Out[74]: True
\end{pythoncode}


En fait, cette syntaxe mystérieuse provient  du fait que Python est un
langage  de  programmation  orientée  objet.  Mais  nous  n'avons  que
quelques minutes pour en parler...




\section{Vocabulaire}


Une \textit{classe} correspond à un \og moule\fg{} permettant de créer
un type d'objet.

Il ne faut pas confondre la classe avec l'objet (il vaut mieux manger
le gâteau que le moule).


Prenons  un exemple:  vous  êtes Saroumane  et vous  avez  un moule  à
orques.     Vous      pouvez     créer     ainsi      une     infinité
d'orques.   Informatiquement    la   classe    \texttt{Orque}   permet
d'\textit{instancier} un objet de type orque.

Un orque a un nom et un poids: ce sont des \textit{attributs} (ses caractéristiques). Il peut
effectuer un salut: c'est une \textit{méthode} (ce que l'objet peut faire).

On résume ceci dans un petit tableau:
\begin{center}
  \begin{tikzpicture}
    \begin{umlclass}{Orque}{nom \\ poids \\ maitre}{salut()}
    \end{umlclass}
  \end{tikzpicture}
\end{center}

En python, je pourrais faire ça:


\begin{pythoncode}
class Orque:

    nom    = ""
    poids  = 0
    maitre = ""

    def salut(self):
        print("Ash nazg durbatulûk! Mon nom est %s" % self.nom)
\end{pythoncode}

et créer des orques:

\begin{pythoncode}
In [76]: a = Orque()

In [77]: a.nom = "Grishnákh"

In [78]: a.salut()
Ash nazg durbatulûk! Mon nom est Grishnákh

In [79]: a.age = 2

In [80]: b = Orque()

In [81]: b.nom = "Uglúk"

In [82]: b.salut()
Ash nazg durbatulûk! Mon nom est Uglúk

In [83]: a.maitre = "Saroumane"

In [84]: b.maitre
Out[84]: 'Sauron'
\end{pythoncode}


Les attributs introduits dans la classe ont des valeurs arbitraires et
on  aurait pu  s'en  passer comme  le  montre la  création  ad hoc  de
l'attribut \texttt{age}.

\medskip

Pour clarifier ceci, Python fournit la fonction \lstinline{__init__()}
(notez bien  les deux horribles  tirets avant et  après \texttt{init})
qui  est  appelée  à  chaque  création d'objet  et  donne  une  valeur
initiale.

On aurait alors pu créer la classe comme ceci:

\begin{pythoncode}
class Orque:

    def __init__(self):
        self.nom    = ""
        self.poids  = 0
        self.maitre = "Sauron"

    def salut(self):
        print("Ash nazg durbatulûk! Mon nom est %s" % self.nom)
\end{pythoncode}

On remarque  aussi qu'une méthode  voulant utiliser un  attribut d'une
classe doit  faire précéder cet attribut  du nom de l'instance  qui la
possède. En python, on utilise le nom standard \texttt{self}.

\medskip

On   peut   aussi   permettre   à   l'utilisateur(rice)   de   choisir
lui(elle)-même les valeurs par défaut. On ajoute alors des arguments à
\lstinline{__init__}:

\begin{pythoncode}
class Orque:

    def __init__(self, nom = "", poids = 0, maitre = "Sauron"):
        self.nom    = nom
        self.poids  = poids
        self.maitre = maitre

    def salut(self):
        print("Ash nazg durbatulûk! Mon nom est %s" % self.nom)
\end{pythoncode}


On peut l'utiliser ainsi:

\begin{pythoncode}
In [106]: a = Orque("Truc",3)

In [107]: a.maitre
Out[107]: 'Sauron'

In [108]: a = Orque("Truc","Sauron")

In [109]: a.maitre
Out[109]: 'Sauron'

In [110]: a.poids
Out[110]: 'Sauron'

In [111]: a = Orque("Truc",100,"Sauron")

In [112]: a.poids
Out[112]: 100

In [113]: a.maitre
Out[113]: 'Sauron'

In [114]: a.nom
Out[114]: 'Truc'
\end{pythoncode}


\section{Héritage}

Imaginez maintenant  que vous  êtes JRR  \textsc{Tolkien} et  que vous
voulez fabriquer  des Hobbits. Vous  vous dites qu'il suffit  de créer
une classe \texttt{Hobbit}:

\begin{center}
  \begin{tikzpicture}
    \begin{umlclass}{Hobbit}{nom \\ prenom \\ poids}{salut()}
    \end{umlclass}
  \end{tikzpicture}
\end{center}


\begin{pythoncode}
class Hobbit:

    def __init__(self, nom = "", prenom = "", poids = 0):
        self.nom    = nom
        self.prenom = prenom
        self.poids  = poids

    def salut(self):
        print("Bonjour! Mon nom est %s %s" % (self.prenom, self.nom))
\end{pythoncode}

qui s'utilise comme d'habitude:

\begin{pythoncode}
In [119]: a = Hobbit("Sacquet", "Bilbo", 50)

In [120]: a.salut()
Bonjour! Mon nom est Bilbo Sacquet
\end{pythoncode}

Et ensuite il y a les Elfes, les Nains, etc.

On remarque cependant  que les Orques comme les Hobbits  ont un nom et
un poids. 

On  peut  alors créer  une  \og  super-classe\fg{} \texttt{Etre}  dont
\texttt{Hobbit}   et  \texttt{Orque}   serait  des   sous-classes  qui
\textit{héritent} de ses attributs:


\begin{pythoncode}
class Etre:

    def __init__(self, appellation = "", poids = 0, bonjour = ""):
        self.appellation = appellation
        self.poids       = poids
        self.bonjour     = bonjour

    def salut(self):
        print("%s ! Mon nom est %s" % (self.bonjour, self.appellation))

    def masse(self):
        print("Je pèse %f kg" % self.poids)


class Orque(Etre):

    def __init__(self,nom = "", poids = 0, maitre = "Sauron"):
        Etre.__init__(self,nom,poids,"Ash nazg durbatulûk")
        self.maitre = maitre

class Hobbit(Etre):

    def __init__(self, nom = "", prenom = "", poids = 0):
        Etre.__init__(self,prenom + ' ' + nom, poids, "Bonjour")
        self.prenom  = prenom
\end{pythoncode}



Alors  \texttt{Hobbit} et  \texttt{Orque}  héritent  des attributs  et
méthodes de \texttt{Etre} alors qu'ils ne sont pas définis dans les sous-classes:

\begin{pythoncode}
In [137]: a = Hobbit("Sacquet", "Bilbo", 50)

In [138]: a.masse()
Je pèse 50.000000 kg

In [139]: a.salut()
Bonjour ! Mon nom est Bilbo Sacquet

In [140]: b = Orque("Uglúk",100)

In [141]: b.salut()
Ash nazg durbatulûk ! Mon nom est Uglúk
\end{pythoncode}


\vfill

\eject



% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \modeexercice
% \section{RECHERCHES}


% % \begin{exercice}[Intégration   numérique:    une   première   approche expérimentale]



  
% % \end{exercice}


% \modenormal

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "PolyIPT2014_15"
%%% End: 
