OOPLesson 2 of 3
Inheritance & ABCs
Inheritance in Python reads almost like JS, minus the keyword. Instead of class Dog extends Animal, you write class Dog(Animal): with the parent in parentheses. Methods are overridden simply by defining a method with the same name in the child class.
Calling the parent uses super(), but with one difference. In JS, super(name) inside a constructor calls the parent constructor. In Python, super() gives you a proxy to the parent, and you call the method you want on it: super().__init__(name) for the constructor, super().speak() for any other method. Unlike JS, Python does not force you to call the parent constructor first (or at all), so forgetting super().__init__ silently leaves parent attributes unset.
Type checks use isinstance(obj, Animal) instead of obj instanceof Animal. isinstance also accepts a tuple, so isinstance(x, (int, float)) checks several types at once. issubclass(Dog, Animal) does the same check on classes.
JS has no abstract classes (only TypeScript's abstract keyword, which disappears at runtime). Python has real ones in the abc module: inherit from ABC and mark methods with @abstractmethod. Python then refuses to instantiate the class, and any subclass that forgets to implement an abstract method fails with TypeError the moment you try to create it, not later when the method is called.
Python also supports multiple inheritance: class C(A, B):. When A and B both define the same method, Python follows the Method Resolution Order (C, then A, then B, then their parents), which you can inspect with C.__mro__. The common, safe use is mixins: small classes that add one capability (like JsonMixin with a to_json method) and get combined with a main base class. That replaces the Object.assign(Proto.prototype, mixin) trick from JS.
Quick reference
| JavaScript | Python | Note |
|---|---|---|
| class Dog extends Animal | class Dog(Animal): | Parent in parentheses |
| super(name) | super().__init__(name) | Call __init__ explicitly |
| super.speak() | super().speak() | super() with parentheses |
| x instanceof Animal | isinstance(x, Animal) | Also accepts a tuple of types |
| abstract class (TS only) | class Shape(ABC): | Enforced at runtime |
| Object.assign mixins | class C(Mixin, Base): | Multiple inheritance + MRO |
Side by side
// JavaScript
class Animal {
constructor(name) { this.name = name; }
speak() { return `${this.name} makes a sound`; }
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // must come first
this.breed = breed;
}
speak() { return super.speak() + " (woof)"; }
}
const d = new Dog("Rex", "lab");
d instanceof Animal; // true
// No runtime abstract classes in JS
class Shape {
area() { throw new Error("not implemented"); }
}# Python
from abc import ABC, abstractmethod
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound"
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
def speak(self):
return super().speak() + " (woof)"
d = Dog("Rex", "lab")
isinstance(d, Animal) # True
issubclass(Dog, Animal) # True
# Real abstract base classes
class Shape(ABC):
@abstractmethod
def area(self): ...
# Shape() -> TypeError: Can't instantiate abstract class
# Mixins via multiple inheritance
class JsonMixin:
def to_json(self):
import json
return json.dumps(self.__dict__)
class Pet(JsonMixin, Animal):
pass
Pet("Tom").to_json() # '{"name": "Tom"}'
Pet.__mro__ # Pet, JsonMixin, Animal, objectExercise
Real Python, running in your browserBuild a small shape hierarchy:
Ctrl + Enter runCtrl + Shift + Enter checkTab indentEsc then Tab to leave the editorCtrl + / comment