--- title: OOP Basics In python - Python Cheatsheet description: Object-Oriented Programming (OOP) is a programming paradigm that revolves around the concept of objects, which are instances of classes. OOP principles are fundamental concepts that guide the design and development of software in an object-oriented way. In Python, OOP is supported by the use of classes and objects. Here are some of the basic OOP principles in Python. --- Object‑oriented programming organises code around **classes** (blueprints) and the **objects** built from them. Data lives in attributes, actions live in methods. ## Defining a Class and Making Instances ```python class Dog: species = "Canis lupus" # one value shared by all dogs def __init__(self, name): # runs when a dog is created self.name = name # unique to each dog def speak(self): return f"{self.name} says Woof!" ``` `Dog("Fido")` makes a new dog. Its name is just for Fido, while `species` lives once in the class. Every instance method needs `self` as the first argument. ### Instance versus Class Attributes ```python fido = Dog("Fido") fido.species = "Mutant" # affects only this object print(Dog.species) # still "Canis lupus" ``` An attribute set on one object stays on that object. A value written in the class body is shared by all objects. ### `__str__` and `__repr__` ```python class Car: def __init__(self, make, year): self.make, self.year = make, year def __str__(self): # friendly text for print() return f"{self.year} {self.make}" def __repr__(self): # precise text for debugging return f"Car({self.make!r}, {self.year})" ``` `__str__` supplies the readable string shown by `print`. `__repr__` supplies an unambiguous string shown in interactive sessions and logs. ## Inheritance (is‑a relationship) ```python class Animal: def __init__(self, name): self.name = name def speak(self): raise NotImplementedError class Cat(Animal): def speak(self): return "Meow!" ``` A child class re‑uses code from its parent and changes only what is different. If the parent’s constructor also needs to run, call it with `super().__init__(...)`. ### Composition (has‑a relationship) ```python class Engine: def __init__(self, hp): self.hp = hp class Vehicle: def __init__(self, engine): self.engine = engine # Vehicle owns an Engine ``` Composition stores one object inside another. Swapping the owned part (for example, a stronger engine) does not require rewriting the outer class. ## Encapsulation ### Name‑mangling ```python class BankAccount: def __init__(self, balance): self.__balance = balance def deposit(self, amount): self.__balance += amount ``` Two underscores change `__balance` into a longer internal name, so outside code won't touch it by mistake. ### `property` for Controlled Access (Optional) ```python class Celsius: def __init__(self, deg): self._deg = deg @property def deg(self): # getter return self._deg @deg.setter def deg(self, value): # setter if value < -273.15: raise ValueError("Below absolute zero") self._deg = value ``` The `@property` decorator lets you read `temp.deg` like a normal attribute which we called it getter, while the paired setter runs validation whenever you assign to it. ## Class Data, Class Methods, and Static Methods ```python class Circle: pi = 3.14159 # stored once in the class def __init__(self, r): self.r = r # radius belongs to one circle @classmethod def unit(cls): # alternative constructor return cls(1) @staticmethod def area(r): # helper that needs no object return Circle.pi * r * r ``` `pi` is a class constant. The `unit` method receives the class (`cls`) so it can create `Circle` objects and still work for subclasses. The `area` method is labelled `@staticmethod` because it relies on neither `self` nor `cls`; it is simply grouped with the class for convenience and is called as `Circle.area(5)`. ## Polymorphism ```python class Rectangle: def __init__(self, w, h): self.w, self.h = w, h def area(self): return self.w * self.h class Circle: def __init__(self, r): self.r = r def area(self): return 3.14 * self.r ** 2 shapes = [Rectangle(3, 4), Circle(2)] areas = [s.area() for s in shapes] # same call, different maths ``` Different classes can answer the same method name (`area`). You can loop over mixed objects without checking their types. ### Operator Overloading ```python class Vector2D: def __init__(self, x, y): self.x, self.y = x, y def __add__(self, other): # enables v + w return Vector2D(self.x + other.x, self.y + other.y) def __len__(self): # enables len(v) return 2 ``` Writing special double‑underscore methods teaches Python's built‑in operators how to work with your objects, making them feel like native types. ## Quick Reference: Common Dunder Methods | Task | Method examples | |-----------|---------------------------------------| | Text | `__str__`, `__repr__` | | Math | `__add__`, `__sub__`, `__mul__`, … | | Compare | `__lt__`, `__eq__`, `__hash__` | | Sequence | `__len__`, `__getitem__`, `__iter__` | --- ## Keywords - **Object Oriented Programming (OOP) (物件導向程式設計)**: A programming paradigm that organizes code using objects and classes to model real-world entities and relationships. - **class (類別)**: A blueprint for creating objects that defines attributes and methods. - **object (物件)**: An instance of a class containing data (attributes) and behavior (methods). - **method (方法)**: A function defined within a class that operates on instances of that class. - **attribute (屬性)**: A variable that is bound to an object or class, holding data relevant to that object. - **constructor (建構子)**: A special method, typically `__init__`, that initializes a new object's state when it is created. - **destructor (解構子)**: A special method, typically `__del__`, that is called when an object is about to be destroyed, used for cleanup. - **dunder method (雙底線方法)**: A special method with double underscores before and after its name (e.g., `__init__`, `__str__`) that enables built-in behaviors. - **inheritance (繼承)**: A mechanism where a new class (child) derives attributes and methods from an existing class (parent), representing a "is-a" relationship. - **parent(base) class (父類別/基礎類別)**: A class whose properties and methods are inherited by another class. - **child(derived) class (子類別/衍生類別)**: A class that inherits from a parent class and can extend or override its behavior. - **override (覆寫)**: To provide a new implementation for an inherited method in a child class. - **composition (複合)**: A design principle where a class is composed of one or more objects of other classes, representing a "has-a" relationship. - **encapsulation (封裝)**: The bundling of data and methods within a class, restricting access to internal details and protecting object integrity. - **private data (私有資料)**: Attributes intended to be hidden from outside access, usually denoted with a leading underscore (e.g., `_data`). - **public data (公有資料)**: Attributes that are accessible from outside the class without restrictions. - **public method (公有方法)**: Methods that are accessible from outside the class without restrictions. - **private method (私有方法)**: A method intended for internal use within a class, typically indicated by a leading underscore. - **utility method (工具方法)**: A method that performs a supportive or common function, often independent of instance-specific data. - **class method (類別方法)**: A method bound to the class rather than an instance, marked with the `@classmethod` decorator, and takes the class as its first parameter. - **class attribute (類別屬性)**: An attribute that is shared among all instances of a class. - **polymorphism (多型)**: The ability for different classes to be treated through a common interface, often by overriding methods. - **function overloading (函數重載)**: Defining multiple functions with the same name but different parameters. - **operator overloading (運算子重載)**: Defining special methods to customize the behavior of built-in operators for user-defined classes. - **method overriding (方法覆寫)**: Providing a new implementation for a method inherited from a parent class, allowing the child class to customize behavior.