a common mistake when using Implicit Satisfaction
Fast recall
Quick revision
Core answer
Practical understanding of Implicit Satisfaction.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
Interface embedding builds bigger interfaces from smaller ones by unioning method lists:
type Reader interface{ Read() string }
type Closer interface{ Close() error }
type ReadCloser interface {
Reader // embeds: adds Read
Closer // embeds: adds Close
}Executed: File with Read and Close satisfies all three — Reader alone, Closer alone, and ReadCloser — because its method set covers each union.
The io package is the canonical showcase: io.ReadWriter, io.ReadCloser, io.ReadWriteCloser, io.ReadWriteSeeker — the standard interfaces are compositions of one- and two-method atoms. The atoms stay tiny; the compositions name the combinations programs actually need; and a type satisfying the atoms satisfies every composition automatically.
What embedding is NOT: inheritance. ReadCloser doesn't extend Reader — it lists Reader's methods alongside Closer's. No hierarchy, no overrides, no dispatch through the embedding; the composed method set is flat.
The design guidance: keep interfaces atom-sized, compose at use sites. Embed interfaces when a COMBINATION is genuinely a named thing (ReadCloser — a thing you read and close), not as a convenience for listing.
a common mistake when using Implicit Satisfaction
Direct Answer
Embedding interfaces inside an interface combines their method lists — the composed interface's method set is the union. io.ReadCloser is Reader + Closer.
Deep Dive & Architecture
The mechanics of the union: the compiler computes an embedded-interface's method set at definition time — the composition is a set of (name, signature) pairs, flattened from the embedded interfaces' own sets (which may themselves be compositions — the flattening is transitive; cycles are a compile error). The result is indistinguishable from having written the methods out: interface{ Reader; Closer } and interface{ Read(); Close() } are the SAME method set — embedding is pure expression, not a new mechanism.
That equivalence has a versioning consequence: if Reader grows a method, every embedded composition grows too — ReadCloser compiled against old-Reader now demands the new method. The io package's stability discipline (Reader and Writer have never changed since Go 1) exists precisely to protect this. When you own the atoms, growing a method in them is a breaking change rippling through every composer.
Embedding a concrete type in an interface is a compile error (interfaces compose interfaces only); embedding an interface in a STRUCT is the delegation pattern — the struct gains the interface's methods as promotion, with the embedded value's implementation behind them. The two embeddings (interface-in-interface for composition, interface-in-struct for delegation) are the twin idioms of Go's interface architecture — same keyword, two orthogonal capabilities, and interviews often probe exactly whether a candidate keeps them separate.
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Implicit Satisfaction, and when would you use it?
- When would you use Implicit Satisfaction in a real project?
- How would you compare Implicit Satisfaction with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.