class Dog(Animal): makes Dog a kind of Animal: it inherits every method and can override the ones that should behave differently. Inside an override, super().__init__(name) runs the parent's version so the shared setup still happens. isinstance(rex, Animal) is true for a Dog.
Methods with double underscores are hooks Python calls for you. __str__ decides what str(obj) and print(obj) show; __repr__ is the developer-facing version shown in lists and the console; __eq__ defines ==; __len__ makes len() work. Defining __str__ is the first one most classes need.
class Shape:
def __init__(self, name):
self.name = name
def __str__(self):
return f"a {self.name}"
class Circle(Shape):
def __init__(self, r):
super().__init__("circle")
self.r = r
print(Circle(2)) # a circleYour task
Write class Animal created with a name, whose speak() returns "..." and whose __str__ returns "<Class name> named <name>", for example "Animal named Rex". Then write class Dog(Animal) whose speak() returns "Woof" and which prints as "Dog named Rex" without redefining __str__ (use the class name from type(self).__name__).
Hint 1
def __str__(self): return f"{type(self).__name__} named {self.name}"
Hint 2
Dog only needs a speak method; everything else is inherited.
Show the solution
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
def __str__(self):
return f"{type(self).__name__} named {self.name}"
class Dog(Animal):
def speak(self):
return "Woof"