{ "cells": [ { "cell_type": "markdown", "id": "49df2691", "metadata": {}, "source": [ "# Classes and Objects\n", "\n", "In brief: \n", "\n", "* **Classes** define a blueprint for creating a kind of value.\n", "* **Objects** are a specific _instance_ of that blueprint.\n", "\n", "\"Instance\" and \"object\" are somewhat interchangeable. These two sentences are roughly equivalent:\n", "\n", "* `2.0` is an instance of the `float` class.\n", "* `2.0` is an object, created based on the `float` class.\n", "\n", "(Note how \"object\" is more general, where instance is usually paired with a class -- to specify an instance of _what_.)" ] }, { "cell_type": "code", "execution_count": 1, "id": "b9876202", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lst = [1, 2, 3]\n", "lst.append(4)\n", "\n", "int(\"1\")" ] }, { "cell_type": "code", "execution_count": 2, "id": "97ac7443", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_list = list([1, 2, 3])\n", "my_list" ] }, { "cell_type": "code", "execution_count": 3, "id": "51394cd4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l1 = [1, 2, 3]\n", "l2 = [1, 2, 3]\n", "l1 is l2" ] }, { "cell_type": "markdown", "id": "69e4334b", "metadata": {}, "source": [ "Create a new class using the `class` keyword. This is akin to using `def` to define a new function." ] }, { "cell_type": "code", "execution_count": 4, "id": "395598ff", "metadata": {}, "outputs": [], "source": [ "class Car:\n", " ..." ] }, { "cell_type": "markdown", "id": "16fccffd", "metadata": {}, "source": [ "You can then create new instances based on that blueprint by \"calling\" the class:" ] }, { "cell_type": "markdown", "id": "13bdc0e0", "metadata": {}, "source": [ "This is also called **_instantiating_** the class; as in, taking the blueprint and creating a specific instance of it.\n", "\n", "You can think of this like manifesting in real life the thing a blueprint describes -- like taking the instructions for an Ikea bookshelf and following its directions to assemble an actual bookshelf." ] }, { "cell_type": "code", "execution_count": 5, "id": "c2bca399", "metadata": {}, "outputs": [], "source": [ "car1 = Car()\n", "car2 = Car()" ] }, { "cell_type": "markdown", "id": "4301714d", "metadata": {}, "source": [ "These two \"cars\" are both the same and totally different. Though based on the same blueprint, they are two _totally distinct and different cars_." ] }, { "cell_type": "code", "execution_count": 6, "id": "08365d81", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(car1) == type(car2)" ] }, { "cell_type": "code", "execution_count": 7, "id": "b5dfd464", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "car1 is car2" ] }, { "cell_type": "markdown", "id": "3ebfdb3a", "metadata": {}, "source": [ "But these cars don't really do anything. It'd be nice to have them have some attributes and capabilities. Let's start by defining an initial color for the cars.\n", "\n", "Like how `[1, 2, 3]` creates a new list with the initial values of `1, 2, 3`, let's make it so that we can do `Car(\"blue\")` to make a new blue car." ] }, { "cell_type": "code", "execution_count": null, "id": "2e949d3f", "metadata": {}, "outputs": [], "source": [ "class Car:\n", " def __init__(self, color):\n", " self.color = color" ] }, { "cell_type": "markdown", "id": "2a13e359", "metadata": {}, "source": [ "A few things happening here:\n", "\n", "1. `__init__`: function to run when creating a new instance\n", "2. `self`, as the first parameter: refers to the specific instance\n", "3. `self.color` vs. just `color`: make sure that we persist that value." ] }, { "cell_type": "code", "execution_count": null, "id": "a8bdd7f2", "metadata": {}, "outputs": [], "source": [ "red_car = Car(\"red\")\n", "blue_car = Car(\"blue\")\n", "\n", "print(red_car.color)\n", "print(blue_car.color)" ] }, { "cell_type": "code", "execution_count": 18, "id": "a135f358", "metadata": {}, "outputs": [], "source": [ "class Car:\n", " def __init__(self, color, battery_size, efficiency):\n", " self.color = color\n", " self.battery_size = battery_size\n", " self.efficiency = efficiency\n", " self.charge_level = 100\n", " \n", " def go(self, distance):\n", " \"\"\"\n", " Note: Does not check for < 0 charge\n", " \"\"\"\n", " spent_kwh = distance / self.efficiency * 100\n", " percent_diff = spent_kwh / self.battery_size\n", " self.charge_level -= percent_diff\n" ] }, { "cell_type": "code", "execution_count": 19, "id": "fb61156d", "metadata": {}, "outputs": [], "source": [ "red_car = Car(\"red\", 125, 3.5)\n", "red_car.go(100)" ] }, { "cell_type": "markdown", "id": "3ad55623", "metadata": {}, "source": [ "## Can classes instantiate other classes?" ] }, { "cell_type": "code", "execution_count": null, "id": "e83a8d45", "metadata": {}, "outputs": [], "source": [ "class University:\n", " def __init__(self):\n", " self.catalog = []\n", "\n", "class Course:\n", " def __init__(self, code, name):\n", " self.code = code\n", " self.name = name\n", " self.enrolled_students = []\n", "\n", " def add_student(self, id):\n", " self.enrolled_students.append(id)" ] }, { "cell_type": "code", "execution_count": null, "id": "a79d4288", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": ".venv", "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.13.3" } }, "nbformat": 4, "nbformat_minor": 5 }