## Understand the different types of methods and how to use them in this Python Class \ > A *method* is a function embedded inside a *class*. \ *A Method* must have at least one parameter. There is no such thing as a parameterless *method*. Typically `self` is used as a parameter in *methods* that don't need any custom parameters. `self` refers to the *object* for which the *method* is called and makes the *object's* *variables* and *methods* available for the method. Using the word `self` is a norm that is typically followed. So even though `self` can be replaced with any other word, doing so will add unnecessary surprises. ## Case Let's assume that from our successful delivery of the first simple project on creating a list with the ability to add and remove elements, we have got a new customer. He wants a similar list but with a slightly *strict* requirement - he wants to restrict the type of elements only to numeric types. \ Since the basic requirements are still the same: \ * It's a list, * It should be able to add and remove elements, * And it should show the entire list. \ We will re-use the class `NumList` that we created earlier and build on that using a *subclass* called `StrictNumList`. Inside `StrictNumList` we can see two *methods* have been defined: `__check_value()`, and `add_value()`. More about this is provided later. \ ```python lass NumList: def __init__(self, name = ""): self.instName = name self.__list = [] def add_value(self, val): self.__list.append(val) def remove_value(self): rv = self.__list[-1] del self.__list[-1] return rv def get_list(self): return self.__list class StrictNumList(NumList): def __init__(self, name): super().__init__(name) def __check_value(self, val): return str(val).isalpha() def add_value(self, val): if not self.__check_value(val): super().add_value(val) else: input_val = input("Insert a number: ") val = float(input_val) super().add_value(val) ``` \ ```python sl01 = StrictNumList(name = "Number List B1") sl01.instName sl01.add_value(2) sl01.add_value("abc") ``` ``` Insert a number: 5 ``` ```python sl01.get_list() ``` ```javascript [2, 5.0] ``` \ ## Constructor - A Special Method `__init__` or Python *constructor* is a special kind of *method* that's used to initiate a *class*. \ * It runs every time the *class* is instantiated and makes the *class* usable. * It must have at least one parameter - `self` to make properties of the *object* available. * Unlike other methods, `__init__` can't return a value or can't be invoked inside or outside of a *class*. For example, you can't create call a method like <`object name`><`.`>`__init__()`. ## 2 Types of Methods Like *variables*, *methods* can be public or private, or better called *partially* private (remember *name mangling*?). ### 1. Private Methods * Naming a private *method* follows the same pattern as the private *variables* - add two underscores (`__`) before the method name. * Name mangling works with *class* name the same way it works with the *variables*. --- **Why Use a Private Method?** The same reason for using a private variable. The primary reason for creating these methods is to be used in other methods thus they don't need to be accessible directly from objects. --- But as we know from the last blog, name mangling actually makes them available. So using the mangled name we can actually access the private methods too. \ In our example class StrictNumList we have created `__check_value()` as a private method. Because its main purpose is to be used inside the `add_value()` method. But check out the below code to see how we can still access this method using the mangled name! \ ```python # calling private method - __check_value() using its mangled name sl01._StrictNumList__check_value('5.5') False ``` \ ### 2. Public Methods Public *methods* can be accessed directly from the *object* using dot notation i.e. <`object name`><`.`><`method name`>. In our example, `add_value()` is a public variable. \ 🛑 But notice how we have defined this method in both the *super* and *subclass*. This is called *method overriding*. \ > Method overriding happens when you define the same method differently in the subclass. \ To use method overriding successfully you need to meet two conditions: \ * It's only possible in the *class* inheritance context. Or in other words, *method* inheritance doesn't work inside the same *class*. * The *subclass* should have the same name and number of parameters as the *superclass*. \ 🛑 Also notice, how the `add_value()` method from the *superclass* was utilized in the `add_value()` method in *subclass* `SuperNumList`. \ ## What's Next Till now in this *OOP in Python* series: \ * We introduced *classes* and their basic building blocks, * We learned about *inheritance* and its application of it using *Subclass*, * We detailed *variables* and, in this post, *methods*. \ In the next post, we will try to get an insider view of the Python *exceptions*. And in doing so, we will see how learning about these topics will come in handy! Happy coding!