|
314 | 314 | ]
|
315 | 315 | },
|
316 | 316 | {
|
317 |
| - "cell_type": "code", |
318 |
| - "execution_count": 4, |
| 317 | + "cell_type": "markdown", |
319 | 318 | "metadata": {},
|
320 |
| - "outputs": [ |
321 |
| - { |
322 |
| - "name": "stdout", |
323 |
| - "output_type": "stream", |
324 |
| - "text": [ |
325 |
| - "I'm tomas, 20 years old. I'm a student\n" |
326 |
| - ] |
327 |
| - } |
328 |
| - ], |
329 | 319 | "source": [
|
330 |
| - "class Animal:\n", |
331 |
| - " SPECIES = 'Unknowm'\n", |
332 |
| - "\n", |
333 |
| - "class Person(Animal):\n", |
334 |
| - " SPECIES = 'Homo Sapiens'\n", |
335 |
| - "\n", |
336 |
| - " def __init__(self, name, age, profession):\n", |
337 |
| - " self.name = name\n", |
338 |
| - " self.age = age\n", |
339 |
| - " self.profession = profession\n", |
340 |
| - " \n", |
341 |
| - " def describe(self):\n", |
342 |
| - " print(f\"I'm {self.name}, {self.age} years old. I'm a {self.profession}.\")\n", |
343 |
| - "\n", |
344 |
| - " def __repr__(self):\n", |
345 |
| - " return f\"Person(name={self.name}, age={self.age}, profession={self.profession})\"\n", |
346 |
| - "\n", |
347 |
| - "tomas = Person(name=\"tomas\", age=20, profession=\"student\")\n", |
348 |
| - "tomas.describe()" |
| 320 | + "We can now represent a person with attributes name, age, and profession. We can introduce a person, and a person can eat." |
349 | 321 | ]
|
350 | 322 | },
|
351 | 323 | {
|
352 | 324 | "cell_type": "markdown",
|
353 | 325 | "metadata": {},
|
354 | 326 | "source": [
|
355 |
| - "**[INSERT diagram for class vs object]**" |
| 327 | + "### Inheritance\n", |
| 328 | + "People with different professions can do different tasks. For example, a doctor can treat a person and a computer scientist\n", |
| 329 | + "can write code.\n", |
| 330 | + "\n", |
| 331 | + "We can define a `ComputerScientist` and `Doctor` class and define any profession-specific tasks for each one.\n", |
| 332 | + "However, computer scientists and doctors are still people, and will also have a name, age, and profession." |
356 | 333 | ]
|
357 | 334 | },
|
358 | 335 | {
|
359 |
| - "cell_type": "markdown", |
| 336 | + "cell_type": "code", |
| 337 | + "execution_count": null, |
360 | 338 | "metadata": {},
|
| 339 | + "outputs": [], |
361 | 340 | "source": [
|
362 |
| - "Let's break this down.\n", |
363 |
| - "\n", |
364 |
| - "First, we have a `Person` class, and `tomas` is an *instance* of `Person`.\n", |
365 |
| - "\n", |
366 |
| - "The functions defined inside the `Person` class, namely `__init__`, `describe`, `__repr__`, are called\n", |
367 |
| - "instance methods and they belong to an instance of `Person` (e.g. `tomas`).\n", |
368 |
| - "\n", |
369 |
| - "They can refer to other methods and attributes that belong to the same object. For example, `describe` refers to the name, age, and profession\n", |
370 |
| - "of the person (an object). This is done using the parameter `self` which refers to the object which \"owns\" this method.\n", |
371 |
| - "\n", |
372 |
| - "You may have also noticed that some of these methods start and end with `__`.\n", |
373 |
| - "These are called *magic methods* and used to defined very specific behaviours.\n", |
374 |
| - "We can create an instance of `Person` by \"calling\" the class as a function, and passing any parameters required e.g.\n", |
375 |
| - "\n", |
376 |
| - "`Person(name=\"tomas\", age=20, profession=\"student\")`.\n", |
| 341 | + "class ComputerScientist:\n", |
| 342 | + " def __init__(self, name, age, profession):\n", |
| 343 | + " self.name = name\n", |
| 344 | + " self.age = age\n", |
| 345 | + " self.profession = \"computer scientist\"\n", |
377 | 346 | "\n",
|
378 |
| - "This will create our object and call `__init__` with our new object (`self`) and any other parameters.\n", |
379 |
| - "`__init__` is called a constructor and it's used to initialize instances of a class. In the example above, we initialize the new `Person` object\n", |
380 |
| - "with the given name, age, and profession. These are called the *instance attributes* and they are attached to an instance of the class.\n", |
| 347 | + " def introduce(self):\n", |
| 348 | + " print(f\"I'm {self.name}, {self.age} years old. I'm a {self.profession}.\")\n", |
| 349 | + " \n", |
| 350 | + " def eat(self, food):\n", |
| 351 | + " return \"\"\n", |
| 352 | + " \n", |
| 353 | + " def write_code(self):\n", |
| 354 | + " print(\"010101010000111001 code go brrrrrr\")\n", |
| 355 | + " \n", |
| 356 | + "class Doctor:\n", |
| 357 | + " def __init__(self, name, age, profession):\n", |
| 358 | + " self.name = name\n", |
| 359 | + " self.age = age\n", |
| 360 | + " self.profession = \"doctor\"\n", |
381 | 361 | "\n",
|
382 |
| - "For example, if we create a new instance of `Person`, the attribute `name` of this instance will be different\n", |
383 |
| - "from the `name` of `tomas`.\n" |
| 362 | + " def introduce(self):\n", |
| 363 | + " print(f\"I'm {self.name}, {self.age} years old. I'm a {self.profession}.\")\n", |
| 364 | + " \n", |
| 365 | + " def eat(self, food):\n", |
| 366 | + " return \"\"\n", |
| 367 | + " \n", |
| 368 | + " def treat_person(self):\n", |
| 369 | + " print(\"Treating a person...\")" |
384 | 370 | ]
|
385 | 371 | },
|
386 | 372 | {
|
387 |
| - "cell_type": "code", |
388 |
| - "execution_count": null, |
| 373 | + "cell_type": "markdown", |
389 | 374 | "metadata": {},
|
390 |
| - "outputs": [], |
391 | 375 | "source": [
|
392 |
| - "other_person = Person(name=\"john doe\", age=55, profession=\"epic rust programmer\")\n", |
| 376 | + "Can you spot what's wrong with the above implementation?\n", |
| 377 | + "We're repeating the code for the constructor, introduce and, eat. The main difference is the profession specific method!\n", |
| 378 | + "What if we want to change how a person should be introduced? We'd have to update the `introduce` method in `Person`, `ComputerScientist`, `Doctor`.\n", |
393 | 379 | "\n",
|
394 |
| - "print(other_person.name)\n", |
395 |
| - "print(tomas.name)" |
| 380 | + "We can use *inheritance* to simplify our code, improve its maintainability, reduce development costs (avoids the scenario above which could introduce bugs!),\n", |
| 381 | + "and avoid repeating code." |
| 382 | + ] |
| 383 | + }, |
| 384 | + { |
| 385 | + "cell_type": "markdown", |
| 386 | + "metadata": {}, |
| 387 | + "source": [ |
| 388 | + "**[INSERT diagram for class vs object]**" |
396 | 389 | ]
|
397 | 390 | },
|
398 | 391 | {
|
|
0 commit comments