|
383 | 383 | },
|
384 | 384 | {
|
385 | 385 | "cell_type": "code",
|
386 |
| - "execution_count": 13, |
| 386 | + "execution_count": null, |
387 | 387 | "metadata": {},
|
388 |
| - "outputs": [ |
389 |
| - { |
390 |
| - "name": "stdout", |
391 |
| - "output_type": "stream", |
392 |
| - "text": [ |
393 |
| - "010101010000111001 code go brrrrrr\n", |
394 |
| - "Treating a person...\n" |
395 |
| - ] |
396 |
| - } |
397 |
| - ], |
| 388 | + "outputs": [], |
398 | 389 | "source": [
|
399 | 390 | "class ComputerScientist(Person):\n",
|
400 | 391 | " def __init__(self, name, age):\n",
|
| 392 | + " \"\"\"\n", |
| 393 | + " We're invoking the constructor of Person,\n", |
| 394 | + " but we set the profession to be \"computer scientist\"\n", |
| 395 | + " \"\"\"\n", |
401 | 396 | " super().__init__(name, age, \"computer scientist\")\n",
|
402 | 397 | " \n",
|
403 | 398 | " def write_code(self):\n",
|
404 | 399 | " print(\"010101010000111001 code go brrrrrr\")\n",
|
405 | 400 | " \n",
|
406 | 401 | "class Doctor(Person):\n",
|
407 | 402 | " def __init__(self, name, age):\n",
|
408 |
| - " super().__init__(name, age, \"computer scientist\")\n", |
| 403 | + " \"\"\"\n", |
| 404 | + " We're invoking the constructor of Person,\n", |
| 405 | + " but we set the profession to be \"doctor\"\n", |
| 406 | + " \"\"\"\n", |
| 407 | + " super().__init__(name, age, \"doctor\")\n", |
409 | 408 | " \n",
|
410 | 409 | " def treat_person(self):\n",
|
411 | 410 | " print(\"Treating a person...\")\n",
|
412 | 411 | "\n",
|
413 | 412 | "donald_knuth = ComputerScientist(\"donald knuth\", 84)\n",
|
| 413 | + "donald_knuth.introduce()\n", |
414 | 414 | "donald_knuth.write_code()\n",
|
415 | 415 | "\n",
|
416 | 416 | "doctor = Doctor(\"John Doe\", 65)\n",
|
| 417 | + "doctor.introduce()\n", |
417 | 418 | "doctor.treat_person()"
|
418 | 419 | ]
|
419 | 420 | },
|
| 421 | + { |
| 422 | + "cell_type": "markdown", |
| 423 | + "metadata": {}, |
| 424 | + "source": [ |
| 425 | + "We define the two classes again with a twist: `Doctor` and `ComputerScientist` now inherit from `Person`.\n", |
| 426 | + "In Python, we can specify the class(es) from which another class inherits from in parenthesis after the class name.\n", |
| 427 | + "\n", |
| 428 | + "```py\n", |
| 429 | + "# Inherit from a single class\n", |
| 430 | + "class Base(Parent1):\n", |
| 431 | + " pass\n", |
| 432 | + "\n", |
| 433 | + "# Inherint from multiple classes\n", |
| 434 | + "class Base(Parent1, Parent2, ...):\n", |
| 435 | + " pass\n", |
| 436 | + "```\n", |
| 437 | + "\n", |
| 438 | + "Further, the `Person` class is said to be the parent class of `Doctor` and `ComputerScientist`.\n", |
| 439 | + "Conversely, the `Doctor` and `ComputerScientist` classes are child classes of the parent `Person`.\n", |
| 440 | + "\n", |
| 441 | + "The child classes will inherit everything from the parent class, and can also *override* any method\n", |
| 442 | + "from the parent classes. In our example, we want instances of `ComputerScientist` to be initialized with the profession \"computer scientist\"\n", |
| 443 | + "and instances of `Doctor` \"doctor\", however, we also want to maintain the functionality of the `Person` constructor.\n", |
| 444 | + "\n", |
| 445 | + "In order to do this, we can override the constructor by re-defining the `__init__` method, and then we call\n", |
| 446 | + "the constructor of the *super* class (that is, the parent class). We can refer to the super class using `super()`,\n", |
| 447 | + "and then we invoke `__init__`: `super().__init__(name, age, \"doctor\")`.\n", |
| 448 | + "\n", |
| 449 | + "```py\n", |
| 450 | + "class Doctor(Person):\n", |
| 451 | + " def __init__(self, name, age):\n", |
| 452 | + " self.name = name\n", |
| 453 | + " self.age = age\n", |
| 454 | + " self.profession = \"doctor\"\n", |
| 455 | + " \n", |
| 456 | + " # ...\n", |
| 457 | + "```\n", |
| 458 | + "\n", |
| 459 | + "The implementation above would also work, however, if there are any changes to the constructor of `Person`, you'd have\n", |
| 460 | + "to copy this over to the new constructor of `Doctor` and `ComputerScientist`.\n", |
| 461 | + "By invoking the constructor of the parent class we avoid repetition of code. However, there may be cases where you'd want to completly change\n", |
| 462 | + "the behaviour of the method, in which case you don't need to invoke the method from the parent class." |
| 463 | + ] |
| 464 | + }, |
420 | 465 | {
|
421 | 466 | "cell_type": "markdown",
|
422 | 467 | "metadata": {},
|
|
429 | 474 | "metadata": {},
|
430 | 475 | "source": [
|
431 | 476 | "TBD:\n",
|
432 |
| - "- polymorphism/abstraction/encapsulation/inheritance a little bit\n", |
| 477 | + "- polymorphism/abstraction/encapsulation a little bit\n", |
433 | 478 | "- attributes (class and instance atttr)\n",
|
434 | 479 | "- inheritance example\n",
|
435 | 480 | "- then intermission on anotations\n",
|
436 | 481 | "- static and class methods"
|
437 | 482 | ]
|
438 | 483 | },
|
439 |
| - { |
440 |
| - "cell_type": "code", |
441 |
| - "execution_count": null, |
442 |
| - "metadata": {}, |
443 |
| - "outputs": [], |
444 |
| - "source": [ |
445 |
| - "class ComputerScientist(Person):\n", |
446 |
| - " def __init__(self, name, age):\n", |
447 |
| - " super().__init__(self, name, age, profession=\"Computer Scientist\")\n", |
448 |
| - "\n", |
449 |
| - " def write_code(self):\n", |
450 |
| - " print(\"print('hello world')\")" |
451 |
| - ] |
452 |
| - }, |
453 | 484 | {
|
454 | 485 | "cell_type": "markdown",
|
455 | 486 | "metadata": {},
|
|
0 commit comments