{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Software Entwicklung \n",
    "\n",
    "## Kapitel 8: Objektorientierung\n",
    "\n",
    "### 8.8 Vererbung\n",
    "\n",
    "Neue Klassen können auch bestehende Klassen erweitern.\n",
    "Die neue Klasse wird von einer oder mehreren *Oberklassen*\n",
    "abgeleitet und ist in dieser Beziehnung die *Unterklasse*.\n",
    "Die Oberklassen werden bei der Klassendefinition\n",
    "zwischen den Klammern angegeben.\n",
    "\n",
    "<code> class Unterklasse(Oberklasse1, Oberklasse2, ...): </code>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Die *Unterklasse* erbt alle Attribute und Methoden\n",
    "der *Oberklassen*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "class Student():\n",
    "\n",
    "    def __init__(self, name):\n",
    "        self.__name = name\n",
    "\n",
    "    def __str__(self):\n",
    "        return self.__name\n",
    "\n",
    "\n",
    "class BMEDStudent(Student):\n",
    "\n",
    "    def get_major_subject(self):\n",
    "        return None\n",
    "\n",
    "\n",
    "s = BMEDStudent(\"Herbert\")\n",
    "print(str(s))\n",
    "print(s.get_major_subject())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "In einer Unterklasse können neue Methoden und\n",
    "Attribute ergänzt sowie geerbte Methoden überschrieben werden."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "class BMMFStudent(BMEDStudent):\n",
    "\n",
    "    def get_favorite_lecture(self):\n",
    "        return \"Software Entwicklung\"\n",
    "\n",
    "    def get_major_subject(self):\n",
    "        return \"MF\"\n",
    "\n",
    "s = BMMFStudent(\"Helga\")\n",
    "print(str(s))\n",
    "print(s.get_major_subject())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Gelegentlich benötigt man in einer Unterklasse Zugriff auf Methoden der Oberklassen\n",
    "in dem Zustand, *bevor* sie überschrieben wurden. Dies kann mit der\n",
    "Built-In Funktion *super* erreicht werden, die das aktuelle Objekt im Gewand der\n",
    "Oberklasse zurückgibt, so dass die Methoden der Oberklasse aufgerufen werden können."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "class BMEIStudent(BMEDStudent):\n",
    "\n",
    "    def get_major_subject(self):\n",
    "        return \"EI\"\n",
    "\n",
    "    def __str__(self):\n",
    "        return super().__str__() + \" \" + self.get_major_subject()\n",
    "\n",
    "s = BMEIStudent(\"Henning\")\n",
    "print(str(s))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 8.9 Polymorphie\n",
    "\n",
    "Der Begriff *Polymorphie* stammt aus dem Griechischen und setzt sich zusammen aus\n",
    "\n",
    "* πολύς (polýs)  = \"viel\"\n",
    "* μορφή (morphé) = \"Gestalt\"\n",
    "\n",
    "Beschrieben wird damit der Umstand, dass der Aufrufer einer Methode nicht genau wissen muss,\n",
    "welches Objekt er vor sich hat, und dennoch die richtige Methode ausgeführt wird."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "from random import random\n",
    "\n",
    "if random() < 0.5:\n",
    "    s = BMMFStudent(\"Hans\")\n",
    "else:\n",
    "    s = BMEIStudent(\"Hannelore\")\n",
    "\n",
    "print(s.get_major_subject())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Die Methode <code>get_major_subject</code> ist im obigen Beispiel *polymorph*.\n",
    "\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
