## Definition
A [[subprogram]] defined within a [[class]] that implements part of the class's behaviour.
*Noun.*
> The `introduce()` method belongs to the `Person` class and prints a greeting.
## Characteristics
- Used in [[object-oriented programming]];
- shares all the key properties of [[subprogram|subprograms]]:
- can take [[parameter|parameters]];
- can contain [[variable|variables]]; and
- can return a value.
- has access to all [[attributes]] of its class regardless of whether they are [[private]] or [[public]];
- called using dot notation on an [[object]], e.g., `object.method()`;
- always has `self` as its first parameter, which refers to the specific object the method is called on[^1]; and
- can be public or private.
## Examples
### Constructor
A [[constructor]] is the method which creates an instance of its class. In Python, this is the `__init__()` method.
```python
class BankAccount:
def __init__(self, p_account_number):
self.account_number = p_account_number
self.__balance = 0
```
### Setters and getters
Both [[setter|setters]] and [[getter|getters]] are examples of methods.
```python
class BankAccount:
...
def get_balance(self):
return self.__balance
def set_balance(self, p_balance):
if p_balance < 0:
raise ValueError("Balance must be >= 0")
else:
self.__balance = p_balance
```
### Public method
Any subprogram defined within a class that is available for use outside of the class definition.
```python
class BankAccount:
...
def deposit(self, p_amount):
if p_amount <= 0:
raise ValueError("Deposit amount must be > 0")
else:
self.__balance = self.__balance + p_amount
```
Note how this subprogram is able to access the `__balance` attribute directly and does not need to use the setter—this is because methods are within the scope of the class definition and so have access to everything whether it is public or private[^2].
### Private method
Any subprogram defined within a class that is only available for use within the class definition, i.e., by other methods of the class.
```python
class BankAccount:
...
def __withdraw(self, p_amount):
if p_amount <= 0:
raise ValueError("Withdrawal amount must be > 0")
elif p_amount <= self.__balance:
self.__balance = self.__balance - p_amount
else:
raise ValueError("Insufficient balance")
return self.__balance
```
## Non-examples
### Subprogram defined in the same file as a class but outside the class definition
Just because a subprogram is defined in the same file as a class, doesn't mean it's a method.
```python
class BankAccount:
...
# this subprogram is not a method of the BankAccount class
def greet(name):
print(f"hello {name}")
greet("Olivia Freeman")
```
## Notes
[^1]: This is true for [[instance]] methods but is not true of class or static methods. Class and static methods aren't covered at this level but could be fun to research yourself.
[^2]: Though often it is easier to reuse your setters and getters, particularly if they enforce validation rules.