Skip to content
IRC-CodingIRC-Coding
InheritanceOOPBase classSubclassOverridingPolymorphismLiskov SubstitutionComposition

Inheritance in OOP: Basics Explained Simply

Learn inheritance in OOP: base classes, subclasses, overriding, polymorphism, Liskov Substitution Principle, and composition vs inheritance.

S

schutzgeist

3 min read
Inheritance in OOP: Basics Explained Simply

Inheritance in OOP Fundamentals – Base Classes, Subclasses, Overriding, Polymorphism, Liskov

This article is a conceptual guide to inheritance in object-oriented programming, including exam questions and key terms.

In a Nutshell

Inheritance lets you define shared properties and behavior in a base class and reuse them in subclasses. The goal is code reuse, polymorphism, and clear type relationships without duplicating code.

Core Technical Definition

Inheritance establishes an is-a relationship between types, where a subclass inherits all public and protected features from the base class and can extend or override them. It enables polymorphism, dynamic binding, and runtime method dispatch based on the actual object type. We distinguish between implementation inheritance and interface inheritance via interfaces. The Liskov Substitution Principle requires that subclasses behave like their base class without surprising clients. Issues like fragile base class, the diamond problem, and tight coupling suggest favoring composition over inheritance when you only need reuse without a true is-a relationship.

Key Exam Points

  • is-a relationship: use correctly, not for has-a relationships
  • Overriding enables polymorphic behavior; method signature must remain compatible
  • Visibility: public, protected, private control inheritance and access
  • IHK-relevant: explain differences between implementation inheritance and interface inheritance
  • Composition over inheritance leads to looser coupling and better substitutability in practice
  • Follow LSP: don’t strengthen preconditions, don’t weaken postconditions, preserve invariants
  • Economic considerations: fewer duplicates, but risk of expensive refactoring with poor hierarchy design
  • Documentation requirements: specify contracts, side effects, override rules, extension points

Core Components

  1. Base class, superclass with shared attributes and methods
  2. Subclass that inherits, extends, overrides
  3. Overriding with dynamic dispatch
  4. Overloading: same method name, different parameters, inheritance not required
  5. Abstract class: shared base with partially implemented behavior
  6. Interface: pure contract for multiple type inheritance
  7. Finality: final keyword prevents overriding and inheritance
  8. Constructor chaining via super calls; initialization order
  9. Access modifiers: protected for extenders, private for strict encapsulation
  10. Testing: substitution tests, contract tests, polymorphism tests

Practical Example

// Example with Java-like syntax showing inheritance and polymorphism
abstract class Shape {
public abstract double area()
}

class Rectangle extends Shape {
private double w, h
public Rectangle(double w, double h) {
if (w <= 0 || h <= 0) throw new IllegalArgumentException("positive dimensions")
this.w = w
this.h = h
}
@Override
public double area() {
return w * h
}
}

class Circle extends Shape {
private double r
public Circle(double r) {
if (r <= 0) throw new IllegalArgumentException("positive radius")
this.r = r
}
@Override
public double area() {
return Math.PI * r * r
}
}

// Polymorphic usage
Shape s1 = new Rectangle(3, 4)
Shape s2 = new Circle(2)
double sum = s1.area() + s2.area()

Explanation: Shape defines the area contract. Subclasses implement it specifically. Calls dispatch polymorphically.

Advantages and Disadvantages

Advantages

  • Code reuse and polymorphism
  • Clear contract through shared interface
  • Eliminates redundant implementations; unified API for clients

Disadvantages

  • Tight coupling to base class decisions
  • Fragile hierarchies make refactoring harder
  • Diamond problem with multiple inheritance; potential encapsulation violations

Typical Exam Questions (with Brief Answers)

  1. Is inheritance appropriate here? Yes, if a true is-a relationship exists and the subclass can be used wherever the base class is expected.

  2. Overriding vs. overloading? Overriding replaces inherited behavior with the same signature in the subclass. Overloading defines multiple methods with the same name but different parameters.

  3. Polymorphism in the context of inheritance? A reference of base type can hold objects of the base class or any subclass. Method calls bind at runtime to the actual object type.

  4. Why composition over inheritance? Composition reduces coupling, avoids rigid hierarchies, enables swappable implementations, and better supports reuse without a true is-a relationship.

  5. What role does protected play? Protected allows subclasses to access members but can weaken encapsulation. Use sparingly; prefer private with accessor methods.

  6. What does the Liskov Substitution Principle require? Don’t strengthen preconditions, don’t weaken postconditions, preserve base class invariants. Otherwise substitutability breaks.

  7. Explain the diamond problem? Multiple inheritance from two base classes that share a common ancestor creates ambiguity. Some languages resolve this with virtual inheritance.

  8. How do you test substitutability? Write contract tests against the base class interface; define the specification and run the same tests against all subclass instances.

Key Sources

  1. https://docs.oracle.com/javase/specs/
  2. https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)
  3. https://martinfowler.com/articles/inheritance.html

Continue Your OOP Learning Path

All OOP articles are now complete. Return to the first article: Object-Oriented Programming OOP Fundamentals.

Back to Blog
Share:

Related Posts