{"post":{"slug":"polymorphism-explained-2026","title":"Polymorphism explained in 2026: one interface, many behaviors","excerpt":"Polymorphism is the object-oriented idea that lets one call do different things depending on the type behind it. Here is the 2026 guide to the kinds of polymorphism and when each one earns its keep.","category":"code","date":"June 30, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">P</span>olymorphism is one of those words that sounds harder than the idea. Strip away the Greek and it means \"many forms\": a single interface that can stand in for many underlying types, each doing the right thing when called. Write code against the shared shape, and the specific behavior gets chosen for you.\n\n## What changed in 2026\n\n- **Interfaces beat inheritance in the mainstream.** Modern style guides across Go, Rust, TypeScript, and even newer Java code favor small interfaces and composition over deep class hierarchies.\n- **Generics landed everywhere.** With Go generics mature and TypeScript generics ubiquitous, parametric polymorphism is now a tool most working developers reach for weekly, not an academic curiosity.\n- **Pattern matching blurred the lines.** Exhaustive pattern matching in more languages gives an alternative to subtype dispatch, so \"add a method to each type\" is no longer the only clean answer.\n\n## The three kinds of polymorphism\n\nMost confusion comes from treating polymorphism as one thing. It is at least three.\n\n- **Subtype (runtime) polymorphism.** A `Shape` reference might point to a `Circle` or a `Square`; calling `area()` dispatches to the right implementation at runtime. This is the classic OOP form.\n- **Parametric polymorphism.** Generics. A `List<T>` works for any `T` without knowing the type in advance. One implementation, many concrete types, checked at compile time.\n- **Ad hoc polymorphism.** Overloading and operator overloading. The same name (`+`, or a function `print`) behaves differently based on argument types.\n\n## Types of polymorphism compared\n\n| Kind | Selected at | Example | Buys you |\n| --- | --- | --- | --- |\n| Subtype | Runtime | `shape.area()` on Circle vs Square | Extensible behavior behind a shared interface |\n| Parametric | Compile time | `List<T>`, `Map<K, V>` | Reuse across types without losing type safety |\n| Ad hoc | Compile time | `add(int, int)` vs `add(str, str)` | Convenient shared names for related operations |\n\nThey are not competitors — real codebases use all three, often in the same file.\n\n## How dynamic dispatch works\n\nSubtype polymorphism usually relies on dynamic dispatch. Under the hood, each object carries a reference to a table of function pointers (a vtable in C++, an interface table elsewhere). When you call `area()`, the runtime looks up the concrete implementation for that object's actual type and jumps to it.\n\nThe cost is one extra indirection and a missed inlining opportunity — usually negligible, occasionally meaningful in hot loops. This is why performance-critical code sometimes prefers generics (resolved at compile time) over virtual calls. If you care about that boundary, the tradeoffs mirror the ones in [compiled vs interpreted languages](/blog/compiled-vs-interpreted-languages-2026).\n\n## When polymorphism earns its keep\n\nPolymorphism pays off when you find yourself writing conditionals that branch on a type tag:\n\n```\n// smell: switching on type\nswitch (shape.kind) {\n  case \"circle\": return Math.PI * r * r;\n  case \"square\": return side * side;\n}\n```\n\nEvery new shape means editing that switch — in every place it appears. Give each type an `area()` method behind a `Shape` interface and adding a triangle touches exactly one new file. That is the real value: new behavior by adding code, not editing existing code.\n\nBut it is not free. Indirection makes control flow harder to follow. If you have exactly two cases that will never grow, a plain conditional is clearer than a class hierarchy.\n\n## Common pitfalls\n\n**Inheritance for code reuse.** The biggest trap. Extending a class just to grab its methods creates a fragile is-a relationship that is not real. Prefer composition or a shared interface.\n\n**Leaky abstractions.** If callers have to type-check or downcast to make the interface work, the polymorphism is fake and the abstraction is wrong.\n\n**Over-generic code.** Parametric polymorphism can be taken too far — a function with five type parameters and three constraints is often harder to read than three concrete functions.\n\n**Deep hierarchies.** Every level of inheritance multiplies the mental model needed to understand behavior. Keep hierarchies shallow.\n\n## FAQ\n\n**Is polymorphism the same as inheritance?**\nNo. Inheritance is one mechanism that enables subtype polymorphism, but interfaces provide it without inheritance, and generics provide a different kind entirely. You can have polymorphism with zero inheritance.\n\n**What is the difference between overloading and overriding?**\nOverloading is ad hoc polymorphism resolved at compile time by argument types. Overriding is subtype polymorphism resolved at runtime by the object's actual type. Different mechanisms, different timing.\n\n**Do dynamic languages have polymorphism?**\nYes, via duck typing — if an object responds to the method you call, it works, regardless of declared type. It is subtype polymorphism without the static contract.\n\n**Is polymorphism slow?**\nRuntime dispatch adds a small indirection cost that rarely matters. When it does, in tight loops, generics or monomorphization avoid it by resolving types at compile time.\n\n## Where to go next\n\n- [Static vs dynamic typing in 2026](/blog/static-vs-dynamic-typing-2026)\n- [Compiled vs interpreted languages in 2026](/blog/compiled-vs-interpreted-languages-2026)\n- [Recursion vs iteration in 2026](/blog/recursion-vs-iteration-2026)","hue":240,"metaTitle":"Polymorphism Explained 2026: OOP Guide","metaDescription":"Polymorphism explained for 2026 — subtype, parametric, and ad hoc polymorphism, how dynamic dispatch works, and when one interface with many behaviors helps.","keywords":["polymorphism explained 2026","what is polymorphism","types of polymorphism","subtype polymorphism","parametric polymorphism generics","ad hoc polymorphism overloading","dynamic dispatch explained","polymorphism in oop","runtime vs compile time polymorphism","polymorphism examples"],"tldr":["**Polymorphism means one interface backing many implementations** — the caller uses a shared shape and the right behavior is selected by type.","**There are several flavors** — subtype (runtime), parametric (generics), and ad hoc (overloading) all count and solve different problems.","**It exists to remove conditionals on type** — instead of a giant switch on kind, each type carries its own behavior.","**Composition often beats deep hierarchies** — reach for interfaces and generics before tall inheritance trees.","**Skip:** inheriting just to reuse code; if the relationship is not a genuine is-a, you are buying coupling you did not need."],"readTime":"4 min read","wordCount":829},"related":[{"slug":"memoization-explained-2026","title":"Memoization explained in 2026: caching results the right way","excerpt":"Memoization trades memory for speed by caching a function output keyed on its inputs. Here is the 2026 guide to how it works, when it helps, and the cache-invalidation traps that bite people.","category":"code","date":"June 29, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":290},{"slug":"what-is-backtracking-2026","title":"What Is Backtracking? A 2026 Practical Guide","excerpt":"Backtracking builds a solution one choice at a time and abandons it the moment it cannot work. This 2026 guide covers the pattern, a worked N-Queens example, and when to use it instead of DP.","category":"code","date":"July 22, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":310},{"slug":"what-is-a-test-double-2026","title":"What Is a Test Double in 2026? The Five Types","excerpt":"A test double is any stand-in object used in place of a real dependency during a test. Dummy, stub, spy, fake, and mock are the five specific kinds, and the differences matter more than the shared name suggests.","category":"code","date":"July 21, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":320}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"pmi-explained-2026","title":"PMI Explained 2026: Private Mortgage Insurance Basics","excerpt":"A clear guide to private mortgage insurance in 2026 — what PMI is, why lenders require it, how much it costs, and the several ways to cancel it or avoid it altogether.","category":"finance","date":"June 30, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},"older":{"slug":"pomodoro-technique-2026","title":"Pomodoro technique in 2026: the focus timer that actually sticks","excerpt":"The Pomodoro technique breaks work into timed focus sprints with short breaks. Here is the 2026 guide to how it works, who it helps, and how to adapt the 25-minute rule instead of quitting it.","category":"guides","date":"June 30, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":150}}