{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tema 09: Herencia en la POO (Enunciados)\n",
    "*Nota: Estos ejercicios son optativos para hacer al final de la unidad y están pensados para apoyar tu aprendizaje*."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**En este ejercicio vas a trabajar el concepto de herencia un poco más en profundidad, aprovechando para introducir un nuevo concepto muy importante que te facilitará mucho la vida.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Hasta ahora sabemos que una clase heredada puede fácilmente extender algunas funcionalidades, simplemente añadiendo nuevos atributos y métodos, o sobreescribiendo los ya existentes. Como en el siguiente ejemplo\n",
    "<br><br>\n",
    "<img src=\"https://docs.hektorprofe.net/cdn/ejemplos_edv/python/EjemploClases.png\" />\n",
    "<br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Color azul, 4 km/h, 150 ruedas, 1200 cc\n"
     ]
    }
   ],
   "source": [
    "class Vehiculo():\n",
    "    \n",
    "    def __init__(self, color, ruedas):\n",
    "        self.color = color\n",
    "        self.ruedas = ruedas\n",
    "        \n",
    "    def __str__(self):\n",
    "        return \"color {}, {} ruedas\".format( self.color, self.ruedas )\n",
    "        \n",
    "        \n",
    "class Coche(Vehiculo):\n",
    "    \n",
    "    def __init__(self, color, ruedas, velocidad, cilindrada):\n",
    "        self.color = color\n",
    "        self.ruedas = ruedas\n",
    "        self.velocidad = velocidad\n",
    "        self.cilindrada = cilindrada\n",
    "        \n",
    "    def __str__(self):\n",
    "        return \"color {}, {} km/h, {} ruedas, {} cc\".format( self.color, self.velocidad, self.ruedas, self.cilindrada )\n",
    "        \n",
    "        \n",
    "c = Coche(\"azul\", 150, 4, 1200)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**El inconveniente más evidente de ir sobreescribiendo es que tenemos que volver a escribir el código de la superclase y luego el específico de la subclase.**\n",
    "\n",
    "Para evitarnos escribir código innecesario, podemos utilizar un truco que consiste en llamar el método de la superclase y luego simplemente escribir el código de la clase:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Color azul, 4 ruedas, 150 km/h, 1200 cc\n"
     ]
    }
   ],
   "source": [
    "class Vehiculo():\n",
    "    \n",
    "    def __init__(self, color, ruedas):\n",
    "        self.color = color\n",
    "        self.ruedas = ruedas\n",
    "        \n",
    "    def __str__(self):\n",
    "        return \"color {}, {} ruedas\".format( self.color, self.ruedas )\n",
    "        \n",
    "        \n",
    "class Coche(Vehiculo):\n",
    "    \n",
    "    def __init__(self, color, ruedas, velocidad, cilindrada):\n",
    "        Vehiculo.__init__(self, color, ruedas)\n",
    "        self.velocidad = velocidad\n",
    "        self.cilindrada = cilindrada\n",
    "        \n",
    "    def __str__(self):\n",
    "        return Vehiculo.__str__(self) + \", {} km/h, {} cc\".format(self.velocidad, self.cilindrada)\n",
    "        \n",
    "        \n",
    "c = Coche(\"azul\", 4, 150, 1200)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** Como tener que determinar constantemente la superclase puede ser fastidioso, Python nos permite utilizar un acceso directo mucho más cómodo llamada super().**\n",
    "\n",
    "Hacerlo de esta forma además nos permite llamar cómodamente los métodos o atributos de la superclase sin necesidad de especificar el self."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "color azul, 4 ruedas, 150 km/h, 1200 cc\n"
     ]
    }
   ],
   "source": [
    "class Vehiculo():\n",
    "    \n",
    "    def __init__(self, color, ruedas):\n",
    "        self.color = color\n",
    "        self.ruedas = ruedas\n",
    "        \n",
    "    def __str__(self):\n",
    "        return \"color {}, {} ruedas\".format( self.color, self.ruedas )\n",
    "        \n",
    "        \n",
    "class Coche(Vehiculo):\n",
    "    \n",
    "    def __init__(self, color, ruedas, velocidad, cilindrada):\n",
    "        super().__init__(color, ruedas)  # utilizamos super() sin self en lugar de Vehiculo\n",
    "        self.velocidad = velocidad\n",
    "        self.cilindrada = cilindrada\n",
    "        \n",
    "    def __str__(self):\n",
    "        return super().__str__() + \", {} km/h, {} cc\".format(self.velocidad, self.cilindrada)\n",
    "\n",
    "    \n",
    "c = Coche(\"azul\", 4, 150, 1200)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Ejercicio\n",
    "Utilizando esta nueva técnica, extiende la clase Vehiculo y realiza la siguiente implementación:\n",
    "<br><br>\n",
    "<img src=\"https://docs.hektorprofe.net/cdn/ejemplos_edv/python/EjercicioClases.png\" />\n",
    "<br>\n",
    "## Experimenta\n",
    "* Crea al menos un objeto de cada subclase y añádelos a una lista llamada vehiculos.\n",
    "* Realiza una función llamada **catalogar()** que reciba la lista de vehiculos y los recorra mostrando el nombre de su clase y sus atributos.\n",
    "* Modifica la función **catalogar()** para que reciba un argumento optativo **ruedas**, haciendo que muestre únicamente los que su número de ruedas concuerde con el valor del argumento. También debe mostrar un mensaje **\"Se han encontrado {} vehículos con {} ruedas:\"** únicamente si se envía el argumento ruedas. Ponla a prueba con 0, 2 y 4 ruedas como valor.\n",
    "\n",
    "*Recordatorio: Puedes utilizar el atributo especial de clase **name** de la siguiente forma para recuperar el nombre de la clase de un objeto:*\n",
    "```python\n",
    "type(objeto).__name__\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "class Vehiculo():\n",
    "    \n",
    "    def __init__(self, color, ruedas):\n",
    "        self.color = color\n",
    "        self.ruedas = ruedas\n",
    "        \n",
    "    def __str__(self):\n",
    "        return \"color {}, {} ruedas\".format( self.color, self.ruedas )\n",
    "        \n",
    "        \n",
    "class Coche(Vehiculo):\n",
    "    \n",
    "    def __init__(self, color, ruedas, velocidad, cilindrada):\n",
    "        super().__init__(color, ruedas)  # utilizamos super() sin self en lugar de Vehiculo\n",
    "        self.velocidad = velocidad\n",
    "        self.cilindrada = cilindrada\n",
    "        \n",
    "    def __str__(self):\n",
    "        return super().__str__() + \", {} km/h, {} cc\".format(self.velocidad, self.cilindrada)\n",
    "\n",
    "    \n",
    "# Completa el ejercicio aquí\n",
    "\n",
    "class Camioneta():\n",
    "    pass\n",
    "\n",
    "\n",
    "class Bicicleta():\n",
    "    pass\n",
    "\n",
    "\n",
    "class Motocicleta():\n",
    "    pass\n",
    "\n",
    "    \n",
    "def catalogar():\n",
    "    pass\n",
    "\n",
    "    \n",
    "def catalogar():\n",
    "    pass"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [default]",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
