class Pet: def __init__(self, n, a): # instance varibles (ie: state data, fields, properties) self.name = n self.age = a self.is_sleeping = False def set_is_sleeping(self, s): # setter is a mutator method self.is_sleeping = s def get_is_sleeping(self): # getter is fruitful if self.is_sleeping: return "Shhh, " + self.name + " is asleep." else: return self.name + " is awake!" def __str__(self): return self.name + " is " + str(self.age) + " years old." class Dog(Pet): def __init__(self, name, age, b): # Pet.__init__(self, name, age) # works, but... super().__init__(name, age) # better to use super(); no need to send self self.breed = b def brush(self): print("Arf! Thanks for the dog brushing!") class Fish(Pet): def __init__(self, name, age, sw): super().__init__(name, age) self.salt_water = sw def change_filter(self): print("Glug! Thanks for changing the filter.") class Rock(Pet): def __init__(self, name, age, c): super().__init__(name, age) self.color = c def set_paint(self, c): self.color = c def __str__(self): return super().__str__() + "It's " + self.color def main(): my_dog = Dog("Chewki", 2, "Giant Chiuaua") print(my_dog) my_dog.brush() if __name__ == "__main__": main()