A class is a way of representing an object with code. A class defines a type with a legal set of values. An objects is an **instance** of a class. ## constructors Classes control how their objects are created and destroyed. The constructor method is a special method for creating a new instance. Constructors ensure the object is properly initialized before any object makes use of it. ## destructors Like constructors, destructors handle the destruction or **finalization** of a class instance. This ensures the object releases all of its resources once it is no longer active. In garbage collected languages, this can be especially important to avoid objects hanging on to resources for a long time. ## inheritance A **subclass** can be defined that includes some elements of the **superclass**; this is called **inheritance**. The subclass can be treated as if it is the superclass, such that code that is built to process the superclass can also apply to the subclass. Inheritance is an example of a [[is-a]] relationship. ## abstract class When a superclass is never truly used, but rather serves as a template for multiple subclasses, is known as an **abstract** class. Abstract classes typically have no initiation method to signify their status as abstract. Classes that are instantiated are **concrete** classes. ## interface An **interface** is a helper class that groups behaviors that might be relevant to some but not all instances of the class. **Generic components** fulfill a similar role. ## function interface The interface of a function or object include what it accepts and what it returns. This "input/output" thinking is an important first step in designing code and a very helpful exercise if you get stuck. ## polymorphism Polymorphism is "being able to refer to different derivations of a class in the same way, but getting the behavior appropriate to the derived class being referred to." -Shalloway/Trott Polymorphism takes different forms: - **Subtype (runtime) polymorphism**: achieved through inheritance. A parent reference can point to child objects, and method **overriding** ensures the correct behavior is called at runtime. - **Ad hoc (compile-time) polymorphism**: achieved via **method overloading** or **operator overloading**, where multiple methods share the same name but differ by parameters or context. - **Parametric polymorphism**: achieved through generics/templates (not built into Python directly). ## operator overloading **Operator overloading** is allowed by some languages like [[Python]]. This allows overloading for example the `__repr__` or `__add__` operators for an object (which change what `print()` and `+` do for the object, respectively). ## method overriding Method overriding happens when a subclass redefines a method from its superclass with the **same name and same signature** but different behavior. Example: ```python class Animal: def speak(self): return "Some sound" class Dog(Animal): def speak(self): # override return "Woof!" ``` ## method overloading Method overloading means defining multiple methods with the same name but different signatures (number or type of parameters). Method overloading is supported in languages like Java and C++ (at compile time). Python does not support true method overloading. Instead, you can simulate it with default arguments, `*args`. Example in Java: ```Java class Calculator { // Add two integers int add(int a, int b) { return a + b; } // Add two doubles double add(double a, double b) { return a + b; } } public class Main { public static void main(String[] args) { Calculator calc = new Calculator(); System.out.println(calc.add(5, 10)); // calls int add System.out.println(calc.add(5.5, 2.3)); // calls double add } } ``` Overloading is both dangerous and powerful. If you overload a method by accident or in a way that is inconsistent, the code may break. ## delegation Delegation is when some other class already exists to handle a request. The host class delegates this request to the existing class. A common example might be using a method in an existing library within a class (e.g., call `requests` inside a class that reads a web page). Delegation is an example of a [[has-a]] relationship. In OOP, we **favor delegation over inheritance**. ## levels of accessibility Class features can be public, protected, and private. - **Public**: accessible from any code - **Protected**: accessible only within the class and its subclasses - **Private**: accessible only within the defining class Different programming languages have different implementations of these levels of accessibility.