inf-abi2027/03 Objektorientierung/01 Objekte/03 Klassen.ipynb

313 lines
7.8 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "0aecbbea-032e-4e23-96b7-baa547ff69a3",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"# Klassen\n",
"\n",
"Mit der Erkenntnistheorie legten Platon und Aristoteles bereits im antiken Griechenland den Grund-\n",
"stein zum Verständnis von Objekten und Klassen. Man spricht dabei von einer \"ist ein\"-Beziehung:\n",
"\n",
"* Herr Herbert Huber *ist eine* Person\n",
"* Herr Huber *ist ein* Patient\n",
"* Herbert *ist ein* Kunde in der örtlichen Bibliothek\n",
"* Mein Toyota Yaris *ist ein* Auto\n",
"* Ein Tesla S *ist ein* Auto"
]
},
{
"cell_type": "markdown",
"id": "fded0977-dda1-4da4-8813-c1721d8e2921",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"## Klassen und Objekte\n",
"\n",
"Die konkreten \"Dinge\" (Herbert, Yaris, Tesla) sind hierbei *Objekte*. Diese werden in die *Klassen* \"Person\", \"Patient\", \"Kunde\" und \"Auto\" eingeteilt. Ein einzelnes Objekt nennt man auch **Instanz**.\n",
"\n",
"Diese Klassifizierung ist grundsätzlich nicht von Natur aus gegeben. Erst durch unsere Beobachtungen werden den Klassen verschiedene Attribute zugewiesen, so haben Objekte\n",
"\n",
"* der Klasse Patient beispielsweise die Attribute \"Name\", \"Krankenkasse\", \"Versicherungsnummer\", \"Krankenvorgeschichte\",...\n",
"* der Klasse Kunde die Attribute \"Name\", \"Kundennummer\",...\n",
"* der Klasse Auto die Attribute \"Farbe\", \"Leistung\", \"Sitzplätze\", \"Antriebsart\",...\n",
"\n",
"An den Klassen \"Patient\" und \"Kunde\" lässt sich erkennen, dass die selbe Person, je nach Kontext unterschiedliche Attribute haben kann."
]
},
{
"cell_type": "markdown",
"id": "f45b9462-6f8b-46ea-a6ea-8a6fad38aed3",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"## Klassendefinition\n",
"\n",
"Wir können eine Klasse, d.h. eine Vorlage für Objekte, mit dem `class` Befehl definieren.\n",
"\n",
"**Wichtig:** Im Gegensatz zum Anlegen eines Objektes, benötigen wir hier kein Komma zur Abtrennung von mehreren Attributen/Methoden!\n",
"\n",
"Konkrete Objekte von dieser Klasse können wir dann mit `new Name()` erzeugen. Die Objekte erhalten automatisch alle Attribute und Methoden der Klasse:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "3259f08f-870f-4851-a9b6-4efa4c77a5e3",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Punkt { x: undefined, y: undefined }\n",
"P(2|-3)\n"
]
}
],
"source": [
"class Punkt {\n",
" x\n",
" y\n",
"\n",
" ausgabe() {\n",
" console.log( 'P(' + this.x + '|' + this.y + ')' )\n",
" }\n",
"}\n",
"\n",
"let p1 = new Punkt()\n",
"\n",
"console.log(p1)\n",
"\n",
"p1.x = 2\n",
"p1.y = -3\n",
"\n",
"p1.ausgabe()"
]
},
{
"cell_type": "markdown",
"id": "951f6268-9350-48c9-8999-fbcd3fd44d19",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"## Konstruktor\n",
"\n",
"Wie wir oben sehen können, sind die Attribute nach Erzeugung des Objektes mit `new Punkt()` noch `undefined`.\n",
"\n",
"In der Regel wollen wir jedoch Attribute direkt beim Anlegen eines Objektes mit Standardwerten initialisieren. Das können wir mithilfe des Konstruktors tun.\n",
"\n",
"Ein Konstruktor ist die Methode mit dem Namen `constructor` und beliebigen Parametern. Diese wird automatisch beim Erzeugen aufgerufen."
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "0ae0a320-0283-48e4-a667-c72bd778befe",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Punkt { x: 0, y: 0 }\n",
"P(2|-3)\n"
]
}
],
"source": [
"class Punkt {\n",
" x\n",
" y\n",
"\n",
" constructor() {\n",
" this.x = 0\n",
" this.y = 0\n",
" }\n",
"\n",
" ausgabe() {\n",
" console.log( 'P(' + this.x + '|' + this.y + ')' )\n",
" }\n",
"}\n",
"\n",
"let p1 = new Punkt()\n",
"\n",
"console.log(p1)\n",
"\n",
"p1.x = 2\n",
"p1.y = -3\n",
"\n",
"p1.ausgabe()"
]
},
{
"cell_type": "markdown",
"id": "8d781c0d-9996-430b-8a52-7b7f1cb3901d",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"Ein Konstruktor kann auch Parameter bekommen. Dann werden die entsprechenden Werte bei `new Punkt(...)` als Parameter mit angegeben:"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "2d8cf85f-71ed-4e83-987e-5289713378b8",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Punkt { x: 5, y: 7 }\n",
"P(2|-3)\n"
]
}
],
"source": [
"class Punkt {\n",
" x\n",
" y\n",
"\n",
" constructor(x, y) {\n",
" if (x !== undefined) {\n",
" this.x = x\n",
" } else {\n",
" this.x = 0\n",
" }\n",
"\n",
" if (y !== undefined) {\n",
" this.y = y\n",
" } else {\n",
" this.y = 0\n",
" }\n",
" }\n",
"\n",
" ausgabe() {\n",
" console.log( 'P(' + this.x + '|' + this.y + ')' )\n",
" }\n",
"}\n",
"\n",
"let p1 = new Punkt(5, 7)\n",
"\n",
"console.log(p1)\n",
"\n",
"p1.x = 2\n",
"p1.y = -3\n",
"\n",
"p1.ausgabe()"
]
},
{
"cell_type": "markdown",
"id": "29cc5ab1-7ce2-4193-a9a2-ee4b24d931b6",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"## Überprüfung auf Typen\n",
"\n",
"Anders als bei anderen Programmiersprachen, können wir bei TypeScript wir lediglich einen Konstruktor anlegen. Dadurch ist es manchmal nötig zu überprüfen, von welchem Datentyp die übergebenen Parameter sind.\n",
"\n",
"Wir können dies mit `typeof p1` machen, hier kommt jedoch nur `object` heraus, nicht der konkrete Typ.\n",
"\n",
"Beispielsweise in `if`-Bedingungen können wir auch mit `p1 instanceof Punkt` konkret abfragen, ob es sich bei der Variablen `p1` um ein Objekt der Klasse `Punkt` handelt."
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "5f355279-c005-4c3b-a436-60f46803c05e",
"metadata": {
"editable": false,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"object\n",
"true\n"
]
}
],
"source": [
"console.log( typeof p1 ) // gibt \"object\" aus\n",
"\n",
"console.log( p1 instanceof Punkt ) // gibt \"true\" aus"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Deno",
"language": "typescript",
"name": "deno"
},
"language_info": {
"codemirror_mode": "typescript",
"file_extension": ".ts",
"mimetype": "text/x.typescript",
"name": "typescript",
"nbconvert_exporter": "script",
"pygments_lexer": "typescript",
"version": "5.8.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}