Why do I have to re-define all of my instance variables in ElectricCar’s __init__?

Question

Why do I have to re-define all of my instance variables in ElectricCar’s init?

Answer

If we override a method, then the new method must be defined in such a way that it does everything you want it to do, which may include everything from the original method! If that’s the case, we’ve learned about calling the parent method by using the super keyword, so that’ll save us some time.
We can just call the parent Car __init__() method by using the super keyword that we learned about earlier, and then add whatever we like afterwards, like this:

def __init__(self, model, color, mpg, battery_type):
    super(ElectricCar, self).__init__(model, color, mpg)
    # Add code to define battery_type instance variable here!

That saves us the trouble of rewriting those lines of code we already wrote, while allowing us to add more to the end for our battery_type!

8 Likes

Why do we need to call the ‘drive_car’ method to change the condition of the car? Shouldn’t it change just by printing out the ‘condition’ once as the whole class will be ran by Python?

Why must we provide the ‘model’, ‘color’, and ‘mpg’ arguments into the init function of the ElectricCar class? Aren’t these already added in from the super call? At the moment, this method just seems like a waste of time as oppose to just redefining the init function. Although, I’m probably wrong.

No, since the instance is an ElectricCar, the values are not passed in to the Car class. We pass all the values into the ElectricCar as parameters, but hand the values up to the Car class to be instantiated.

 super().__init__(params)

invokes the __init__ method of the super class and initializes the parameters so the derived class will have those attributes set.

2 Likes

Hi, this could be myopic to the extent of the exercise and/or dated to Py2 but still thought it worth sharing: (considered posting on How can I define and use a __repr__ method? but I think this is better off here)

I follow the logic of a super call to the Parent class at initialization of a Child class with both inherited and additional variables and methods. Had a mega aha moment when I realized our display_car method was really a __repr__()

So I defined a representation for Parent that’s super called at Child ‘re’-representation.

It makes sense to me in this delimited context, and certainly pieced and cleaned everything together from the lesson (for me). But I’m curious if this is an ideal/honest use of __repr__() for an instance of a derived class…

class Car(object):
  condition = "new"
  def __init__(self, model, color, mpg):
    self.model = model
    self.color = color
    self.mpg   = mpg

  def drive_car(self):
    self.condition = "used"
  
  def __repr__(self):
    return "This is a %s %s %s with %s MPG" % (self.condition, self.color, self.model, str(self.mpg))

class ElectricCar(Car):
  def __init__(self, model, color, mpg, battery_type):
    super(ElectricCar, self).__init__(model, color, mpg)
    self.battery_type = battery_type

  def drive_car(self):
    self.condition = "pretty good"

  def __repr__(self):
    return super(ElectricCar, self).__repr__() + " on a %s battery" % (self.battery_type)


my_car = ElectricCar("DeLorean", "silver", 88, "molten salt")

my_car.drive_car()
print my_car 

#This is a pretty good silver DeLorean with 88 MPG on a molten salt battery#