{"id":1084,"date":"2026-08-17T00:32:02","date_gmt":"2026-08-17T00:32:02","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1084"},"modified":"2026-08-17T00:32:03","modified_gmt":"2026-08-17T00:32:03","slug":"go-tutorials-composition-instead-of-classical-inheritance","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/go-tutorials-composition-instead-of-classical-inheritance\/","title":{"rendered":"Go Tutorials: Composition Instead of Classical Inheritance"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This is one of the most important mindset changes when coming to Go from Java, C++, C#, or Python.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The key idea is simple:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Inheritance says:<\/strong> \u201cI am a type of something.\u201d<br><strong>Composition says:<\/strong> \u201cI contain something and use its functionality.\u201d<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Go deliberately does <strong>not<\/strong> have classical inheritance such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Dog extends Animal<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead, Go encourages you to build larger types by combining smaller types.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is composition?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose we have a <code>Car<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A car needs an engine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In an inheritance-heavy design, you might be tempted to think about parent and child classes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With composition, you simply say:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Car HAS an Engine<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Car IS an Engine<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That distinction is the heart of composition.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    Car&#91;Car] --&gt;|has an| Engine&#91;Engine]\n    Engine --&gt; Start&#91;\"Start()\"]\n    Car --&gt; Drive&#91;\"Drive()\"]<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2. Complete Go Example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Copy-paste this entire program into <code>main.go<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\n\/\/ Engine is a small independent type.\n\/\/ It knows how to start itself.\ntype Engine struct {\n\tHorsePower int\n}\n\n\/\/ Start belongs to Engine.\nfunc (e Engine) Start() {\n\tfmt.Println(\"Engine started\")\n}\n\n\/\/ Car is made by COMPOSING smaller things together.\n\/\/\n\/\/ A Car HAS an Engine.\n\/\/ Car does not inherit from Engine.\ntype Car struct {\n\tBrand  string\n\tEngine Engine\n}\n\n\/\/ Drive belongs to Car.\n\/\/\n\/\/ Car can use the behavior of the Engine\n\/\/ because Car contains an Engine.\nfunc (c Car) Drive() {\n\tc.Engine.Start()\n\n\tfmt.Printf(\n\t\t\"%s is driving with %d HP\\n\",\n\t\tc.Brand,\n\t\tc.Engine.HorsePower,\n\t)\n}\n\nfunc main() {\n\t\/\/ Create an Engine.\n\tengine := Engine{\n\t\tHorsePower: 150,\n\t}\n\n\t\/\/ Put the Engine inside the Car.\n\tcar := Car{\n\t\tBrand:  \"Toyota\",\n\t\tEngine: engine,\n\t}\n\n\t\/\/ Car uses its composed Engine internally.\n\tcar.Drive()\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Output<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Engine started\nToyota is driving with 150 HP<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. What exactly happened?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Start with this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type Engine struct {\n\tHorsePower int\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Engine<\/code> is an independent type.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It has its own behavior:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func (e Engine) Start() {\n\tfmt.Println(\"Engine started\")\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then we create another type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type Car struct {\n\tBrand  string\n\tEngine Engine\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This line is the important part:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Engine Engine<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It means:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">A <code>Car<\/code> contains an <code>Engine<\/code>.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">That is <strong>composition<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Car\n\u251c\u2500\u2500 Brand\n\u2514\u2500\u2500 Engine\n    \u2514\u2500\u2500 HorsePower<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>Car<\/code> can therefore use its engine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>c.Engine.Start()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and access its data:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>c.Engine.HorsePower<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. Why does Go prefer composition?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Because large inheritance hierarchies can become tightly coupled.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine something like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Vehicle\n   \u2193\nCar\n   \u2193\nElectricCar\n   \u2193\nAutonomousElectricCar\n   \u2193\nDeliveryAutonomousElectricCar<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Changes in a parent class can affect many child classes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Composition usually creates smaller independent pieces:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TD\n    Car --&gt; Engine\n    Car --&gt; GPS\n    Car --&gt; Battery\n    Car --&gt; Brakes<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A <code>Car<\/code> becomes a combination of components.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Car\n\u251c\u2500\u2500 Engine\n\u251c\u2500\u2500 GPS\n\u251c\u2500\u2500 Battery\n\u2514\u2500\u2500 Brakes<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is generally easier to understand and change.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. Classical Inheritance vs Go Composition<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Classical Inheritance<\/th><th>Go Composition<\/th><\/tr><\/thead><tbody><tr><td>Child extends parent<\/td><td>Struct contains another type<\/td><\/tr><tr><td><code>Dog extends Animal<\/code><\/td><td><code>Dog<\/code> contains useful components<\/td><\/tr><tr><td>Usually represents <strong>is-a<\/strong><\/td><td>Usually represents <strong>has-a<\/strong><\/td><\/tr><tr><td>Behavior inherited from parent<\/td><td>Behavior is used through contained types<\/td><\/tr><tr><td>Can create deep class hierarchies<\/td><td>Usually creates small independent components<\/td><\/tr><tr><td>Parent and child can become tightly coupled<\/td><td>Components are easier to replace<\/td><\/tr><tr><td>Common in Java\/C++\/C#<\/td><td>Preferred approach in Go<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The easiest memory trick is:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Relationship<\/th><th>Think<\/th><\/tr><\/thead><tbody><tr><td>Inheritance<\/td><td><strong>IS-A<\/strong><\/td><\/tr><tr><td>Composition<\/td><td><strong>HAS-A<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For our example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Car HAS-A Engine<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So composition is natural.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. How do I recognize composition in Go?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Look for one struct containing another type.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type Engine struct {\n\tHorsePower int\n}\n\ntype Car struct {\n\tEngine Engine\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read it naturally:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><code>Car<\/code> has an <code>Engine<\/code>.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Then you usually access it like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>car.Engine.Start()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This explicit style is very common and very easy to understand.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. Where should I use composition?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use composition when one thing <strong>uses, contains, owns, or depends on<\/strong> another thing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Car        HAS Engine\nComputer   HAS CPU\nOrder      HAS Customer\nServer     HAS Logger\nUser       HAS Address\nGame       HAS Player\nApp        HAS Database<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These naturally become structs containing other structs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type Address struct {\n\tCity string\n}\n\ntype User struct {\n\tName    string\n\tAddress Address\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is composition too.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. When should I use it?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Whenever you find yourself thinking:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">&#8220;This struct needs functionality\/data provided by another thing.&#8221;<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type Server struct {\n\tLogger Logger\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server.Logger.Log()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Rather than creating strange inheritance relationships.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. The important mindset<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">If you come from Java, you might initially think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>What should my parent class be?<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In Go, try changing the question to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>What small pieces does my type need?<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then combine those pieces.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Instead of:\n\nAnimal\n  \u2193\nDog\n\nThink:\n\nDog\n\u251c\u2500\u2500 Name\n\u251c\u2500\u2500 Legs\n\u2514\u2500\u2500 Behavior<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Go encourages building programs from <strong>small cooperating types<\/strong>, rather than large inheritance trees.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. Don&#8217;t confuse composition with copying<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">When we write:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type Car struct {\n\tEngine Engine\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">we are not copying the <code>Engine<\/code> code into <code>Car<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We are saying:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Car owns\/contains an Engine value.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>car.Engine.Start()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Car\n \u2193\nEngine\n \u2193\nStart()<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. One-line definition to remember<\/h1>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Composition in Go means building a type by combining other types instead of inheriting from a parent class.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">The basic pattern is simply:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type SmallThing struct {\n}\n\ntype BiggerThing struct {\n\tSmall SmallThing\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read it as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>BiggerThing HAS-A SmallThing<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Final mental model<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    A&#91;\"Classical OOP\"] --&gt; B&#91;\"Parent\"]\n    B --&gt; C&#91;\"Child inherits behavior\"]\n\n    D&#91;\"Go\"] --&gt; E&#91;\"Small Type A\"]\n    D --&gt; F&#91;\"Small Type B\"]\n    E --&gt; G&#91;\"Composed Type\"]\n    F --&gt; G<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When writing Go, prefer thinking:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Build with pieces<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">rather than:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Build with parent\/child classes<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So for this example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type Car struct {\n\tEngine Engine\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is the core idea.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Car has an Engine \u2192 composition.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Not:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Car extends Engine \u2192 inheritance.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is one of the most important mindset changes when coming to Go from Java, C++, C#, or Python. The key idea is simple: Inheritance says: \u201cI&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1084","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1084","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1084"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1084\/revisions"}],"predecessor-version":[{"id":1085,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1084\/revisions\/1085"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1084"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1084"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1084"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}