{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Software Entwicklung \n",
    "\n",
    "## Kapitel 8: Objektorientierung\n",
    "\n",
    "### 8.1 Objekte\n",
    "\n",
    "Bisher haben wir *Daten* und *Funktionen* getrennt betrachtet.\n",
    "Bei einem Objekt werden Daten (auch: *Attribute*) und Funktionen\n",
    "(auch: *Methoden*) an einer Stelle zusammengefasst.\n",
    "\n",
    "Die Methoden eines Objekts können - neben lokalen Variablen, globalen Variablen\n",
    "und Parametern - auch die Attribute des Objekts nutzen. So kann\n",
    "z.B. ein Datumsobjekt die Attribute \"Jahr\", \"Monat\" und \"Tag\" besitzen\n",
    "und die Methoden des Objekts auf Basis dieser Attribute den\n",
    "Wochentag (0: Montag, ..., 6: Sonntag) ausrechnen oder eine standardisierte\n",
    "Stringrepräsentation generieren.\n",
    "\n",
    "![Datum-Objekt](../img/object.png \"Datum-Objekt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Datumsobjektsobjekte können mit Hilfe des Standardmoduls <code>datetime</code>\n",
    "generiert werden. Die Methoden eines Objekts werden stets mit der Dot-Notation\n",
    "aufgerufen."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "import datetime\n",
    "\n",
    "d = datetime.date(1989, 11, 9)\n",
    "print(d.weekday())\n",
    "print(d.isoformat())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 8.2 Klassen\n",
    "\n",
    "Der Bauplan für Datumsobjekte, der die Attribute und Methoden festlegt,\n",
    "wird als *Klasse* bezeichnet. Das Standardmodul <code>datetime</code>\n",
    "enthält einen Bauplan für Datumsobjekte in Form der Klasse <code>date</code>.\n",
    "\n",
    "Objekte, die gemäß eines solchen\n",
    "Bauplans generiert wurden, haben die Klasse als Datentyp."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "print(type(d))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 8.3 Instanzen\n",
    "\n",
    "Der Bauplan, den eine Klasse bereitstellt, kann *mehrfach* benutzt werden, um\n",
    "mehrere Objekte zu erzeugen. Man spricht hier von *Instanzen* der Klasse."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "d1 = datetime.date(2000, 1, 1)\n",
    "d2 = datetime.date(2010, 1, 1)\n",
    "d3 = datetime.date(2020, 1, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Die Attribute der Instanzen sind voneinander unabhängig, d.h.\n",
    "anders als globale Variablen mehrfach vorhanden. Die Methoden, die\n",
    "ja stets mit der Dot-Notation für eine spezifische Instanz aufgerufen\n",
    "werden, nutzen die Attribute ihrer jeweiligen Instanz und liefern daher\n",
    "ggf. unterschiedliche Werte."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "print(d1.weekday())\n",
    "print(d2.weekday())\n",
    "print(d3.weekday())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Welche Attribute und Methoden ein Objekt besitzt, ist normalerweise\n",
    "der Dokumentation oder dem Programmcode der Klasse zu entnehmen.\n",
    "Es gibt jedoch mit der Built-In-Funktion <code>dir</code> auch\n",
    "eine Möglichkeit, diese Information programmatisch zu ermitteln."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "print(dir(d1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Beim betrachteten Datumsobjekt *beginnen und enden* einige der Methoden-\n",
    "und Attributsnamen mit einem doppelten Unterstich <code>\\_\\_</code>, im\n",
    "Python-Jargon auch *dunder methods* bzw. *dunder attributs* genannt.\n",
    "Diese Methoden und Attribute werden vom Python-System verwendet und\n",
    "dürfen nicht überschrieben werden! Ein bereits bekanntes Beispiel ist\n",
    "die Variable <code>\\_\\_name\\_\\_</code>, die den aktuellen Modulnamen \n",
    "oder den Wert <code>\\_\\_main\\_\\_</code> enthält."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "print(__name__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Auch die Definition eigener\n",
    "Funktionen und Variablen, die mit einem Doppel-Unterstich beginnen\n",
    "und enden, sollte vermieden werden. Es könnte andere Entwickler\n",
    "irritieren und System-Funktionen und -Variablen\n",
    "künftiger Python-Versionen verdecken."
   ]
  }
 ],
 "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
}
