python-crash-course-book/chap9_classes.md

5.8 KiB
Raw Blame History

Chapter 9. Classes

Objectives:

  • Making an object from a class is called instantiation, and you work with instances of a class.
  • In this chapter youll write classes and create instances of those classes.
  • Youll specify the kind of information that can be stored in instances, and youll define actions that can be taken with these instances.
  • Youll also write classes that extend the functionality of existing classes, so similar classes can share code efficiently.
  • Youll store your classes in modules and import classes written by other programmers into your own program files.

Creating and using a class

class Dog:
    """A Simple attempt to model a dog"""

    def __init__(self, name, age):
        """Initialize name and age attributes."""
        self.name = name
        self.age = age
    
    def sit(self):
        """Simulate a dog sitting in response to a command."""
        print(f"{self.name} is now sitting.")

    def roll_over(self):
        """Simulate rolling over in response to a command"""
        print(f"{self.name} rolled over!")

init() method

  • A special method python run automatically whenever we create a new instance.
  • self in parameters is required in method definition, always come first
    • So method call will automatically pass the self argument, it's a reference to itself.

Making an Instance from a Class

my_dog = Dog('Willie', 6)

(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")

Accessing Attributes

my_dog.name

Calling Methods

class Dog:
    --snip--

my_dog = Dog('Willie', 6)
my_dog.sit()
my_dog.roll_over()

Creating Multiple Instances

class Dog:
    --snip--

my_dog = Dog('Willie', 6)
your_dog = Dog('Lucy', 3)

print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")
my_dog.sit()

print(f"\nYour dog's name is {your_dog.name}.")
print(f"Your dog is {your_dog.age} years old.")
your_dog.sit();

Working with Classes and Instances

After we create class, we can edit object

  • need write getter/setter functions to access attributes
  • may need default value for attribute
class Car:
    """A simple attempt to represent a car."""

    def __init__(self, make, model, year):
        """Initialize attributes to describe a car."""
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        """Return a neatly formatted descriptive name."""
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()

    def read_odometer(self):
           """Print a statement showing the car's mileage."""
           print(f"This car has {self.odometer_reading} miles on it.")
    
    def update_odometer(self, mileage):
        """Set the odometer reading to the given value."""
        self.odometer_reading = mileage

my_new_car = Car('audi', 'a4', 2019)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(23)
my_new_car.read_odometer()
  • get_descriptive_name() is a getter function, so we can get private attributes
  • odometer_reading has default value as 0

Inheritance

Use inheritance when the class is a specialized version of another class.

  • When one class inherits from another, it takes on the attributes and methods of the first class.
  • Original class is called parent class, New class is called child class
  • Child class can define new attributes/methods

init() for a Child Class

Creating a __init__() of a child class:

  1. Call __init__() from parent class use super().__init__(), to initialize parent's attributes (as shown below)
  2. Add specialized attributes
class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""

    def __init__(self, make, model, year):
        """Initialize attributes of the parent class."""
        super().__init__(make, model, year)
  • super() is a special function that allows us to call a method from parentclass. It will initialize all inherited attributes for ElectricCar

Defining Attributes and Methods for the Child Class

Add attributes/methods for child class

class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""

    def __init__(self, make, model, year):
        """
        Initialize attributes of the parent class.
        Then initialize attributes specific to an electric car.
        """
        super().__init__(make, model, year)
        self.battery_size = 75

    def describe_battery(self):
        """Print a statement describing the battery size."""
        print(f"This car has a {self.battery_size}-kWh battery.")
  • self.battery_size is attribute unique to ElectricCar, not for any parent class
  • You can add attribute/method for child class as many as you want.

Overriding Methods from Parent Class

Python can disregard parent class's method and only use redefined method in child class

class Car:
    """A simple attempt to represent a car."""

    def __init__(self, make, model, year):
        """Initialize attributes to describe a car."""
        ...
        self.gas_tank = 0

    ...

    def fill_gas_tank(self, gas):
        """Add gas into tank"""
        self.gas_tank = self.gas_tank + gas

class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""
    
    ...

    def fill_gas_tank(self):
        """Electric cars don't have gas tanks"""
        print("This car doesn't need gas tank!")
  • fill_gas_tank() override parent method, with argument list changed

Instance as Attributes

Sometimes we can use an instance of an class (object) as an attribute of another class.

e.g. After grouping multiple all battery related attributes/method into a new class