Inheritance is a feature of object-oriented programming that lets one type reuse and extend the data and behavior of another. You define a general parent type, then create more specific child types that automatically get everything the parent has, plus their own additions. The classic example: an Animal type with a move method, and a Dog type that inherits move while adding bark. The aim is reuse, but modern advice in 2026 is to reach for it carefully, because overusing it creates brittle code.
How inheritance works
A child type, sometimes called a subclass, declares that it extends a parent type, the superclass. From that point the child has access to the parent properties and methods as if they were its own. You write the shared logic once in the parent and the specifics in each child.
// Dog inherits move from Animal and adds its own speak
class Animal {
move() { return "moving"; }
}
class Dog extends Animal {
speak() { return "woof"; }
}
const d = new Dog();
d.move(); // inherited, returns "moving"
d.speak(); // returns "woof"
Inheritance only makes sense when the child genuinely is a kind of the parent. This builds on the basics of what an object in programming is in 2026.
The is-a test
The quickest way to judge whether inheritance fits is the is-a relationship. Ask whether the child truly is a kind of the parent:
- A Dog is an Animal. Inheritance fits.
- A Car has an Engine. That is a has-a relationship, not is-a, so composition fits better.
Getting this wrong is the root of most inheritance pain. If you find yourself inheriting just to grab a method, you probably wanted composition instead.
Overriding behavior
A child can replace an inherited method with its own version, called overriding. The parent defines a default; the child specializes it. This is how a generic Shape with an area method can have a Circle and a Square that each compute area their own way, while code that uses any Shape stays the same.
Inheritance versus composition
| Approach |
Relationship |
Flexibility |
Risk |
| Inheritance |
is-a |
Rigid once set |
Deep chains get brittle |
| Composition |
has-a |
Mix and match parts |
Slightly more wiring |
The widely shared guidance is to favor composition over inheritance. Composition builds objects from smaller pieces you combine, which adapts more easily as requirements change. Inheritance is still useful, but a shallow hierarchy beats a deep one almost every time. It also pairs with encapsulation in 2026, which keeps each piece self-contained.
What to skip
- Deep inheritance trees. Four or five layers of parents make a change anywhere ripple unpredictably.
- Inheriting for code reuse alone. If the is-a test fails, compose instead of inherit.
- Overriding to remove behavior. If a child has to disable half of what it inherits, the hierarchy is wrong.
- Treating inheritance as the default. Start with simple objects and composition; add inheritance only when an is-a relationship is real.
FAQ
What is the difference between a parent and child class?
A parent, or superclass, defines shared data and behavior. A child, or subclass, inherits all of that and can add to it or override parts of it. The child is a more specific version of the parent.
What does overriding mean?
Overriding is when a child provides its own version of a method it inherited, replacing the parent default behavior for instances of that child.
Is inheritance the same as composition?
No. Inheritance models an is-a relationship by extending a type. Composition models a has-a relationship by building an object out of smaller parts. Composition is usually the more flexible choice.
Why do people say to avoid inheritance?
Not to avoid it entirely, but to avoid deep hierarchies. Long inheritance chains become rigid and hard to change, so favor shallow inheritance or composition where possible.
Where to go next
See what an object in programming is in 2026, what encapsulation is in 2026, and what a method is in 2026.