# Classes and methods

Defining classes and methods

```python
class ClassName:
    def method_name(self, other_parameters):
        body_of_method
```

##### Special methods

- Special methods start and end with `<var>__</var>`.
- Special methods have specific names, like <var>`__init__` </var>for the constructor or `<var>__str__</var>` for the conversion to string.
- The methods `<var>__str__</var>` and `<var>__repr__</var>` allow you to define human-readable and unambiguous string representations of your objects, respectively.
- By defining methods like `<var>__eq__</var>`, `<var>__ne__</var>`, `<var>__lt__</var>`, `<var>__gt__</var>`, `<var>__le__</var>`, and<var> `__ge__`</var>, you can control how <var>objects</var> of your <var>class</var> are compared.

With the `__init__` method:

用途：接受參數的傳入，並帶入變數 self.XXX

```python
class Apple:
    def __init__(self, color, flavor):
        self.color = color
        self.flavor = flavor

honeycrisp = Apple("red", "sweet")
fuji = Apple("red", "tart")
print(honeycrisp.flavor)
print(fuji.flavor)
```

With the `__str__` method:

When you `print()` something, Python calls the object’s `__str__()` method and outputs whatever that method returns

```python
class Apple:
    def __init__(self, color, flavor):
        self.color = color
        self.flavor = flavor

    def __str__(self):
        return "an apple which is {} and {}".format(self.color, self.flavor)

honeycrisp = Apple("red", "sweet")
print(honeycrisp)

# prints "an apple which is red and sweet"
```

With the custom method

```python
class Triangle:
    def __init__(self, base, height):
        self.base = base
        self.height = height
    def area(self):
        return 0.5 * self.base * self.height
    def __add__(self, other):
        return self.area() + other.area()
    
triangle1 = Triangle(10, 5)
triangle2 = Triangle(6, 8)
print("The area of triangle 1 is", triangle1.area())
print("The area of triangle 2 is", triangle2.area())
print("The area of both triangles is", triangle1 + triangle2)
```