
- Go - Home
- Go - Overview
- Go - Environment Setup
- Go - Program Structure
- Go - Basic Syntax
- Go - Data Types
- Go - Variables
- Go - Constants
- Go - Identifiers
- Go - Keywords
- Go - Operators
- Go - Arithmetic Operators
- Go - Assignment Operators
- Go - Relational Operators
- Go - Logical Operators
- Go - Bitwise Operators
- Go - Miscellaneous Operators
- Go - Operators Precedence
- Go Decision Making
- Go - Decision Making
- Go - If Statement
- Go - If Else Statement
- Go - Nested If Statements
- Go - Switch Statement
- Go - Select Statement
- Go Control Flow Statements
- Go - For Loop
- Go - Nested for Loops
- Go - Break Statement
- Go - Continue Statement
- Go - Goto Statement
- Go Functions
- Go - Functions
- Go - Call by Value
- Go - Call by Reference
- Go - Functions as Values
- Go - Function Closure
- Go - Function Method
- Go - Anonymous function
- Go Strings
- Go - Strings
- Go - String Length
- Go - String Concatenation
- Go - Compare Strings
- Go - Split String
- Go - Substring Extraction
- Go - String Replacement
- Go - String Interpolation
- Go - Parse Date Strings
- Go Arrays
- Go - Arrays
- Go - Multidimensional Arrays
- Go - Multidimensional Arrays
- Go - Passing Arrays to Functions
- Go - Pointers
- Go - Pointers
- Go - Array of pointers
- Go - Pointer to pointer
- Go - Passing pointers to functions
- Go Advanced Control Structures
- Go - Scope Rules
- Go - Dereferencing Pointer
- Go - Structures
- Go - Slice
- Go - Slice of Slices
- Go - Range
- Go - Maps
- Go - Recursion
- Go - Type Casting
- Go - Interfaces
- Go - Type Assertion
- Go - Error Handling
- Go - Concurrency
- Go - Regular Expression
- Go - Inheritance
- Go - Packages
- Go - Templates
- Go - Reflection
- Go - Generics
- Go File Handling
- Go - Read File By Word
- Go - Read File By Line
- Go - Read CSV Files
- Go - Delete File
- Go - Rename & Move File
- Go - Truncate a File
- Go - File Read-Write Mode W/O Truncation
- Go Miscellaneous
- Go - defer Keyword
- Go - Fmt Package
- Go - Zero Value
- Go - Import
Go - Inheritance
Inheritance is a very important concept in Object-Oriented Programming(OOPS) like (e.g: Java, C++) where a class (subclass or derived class) inherits properties and methods from another class (superclass or base class). But in Golang, there is no class or inheritance. Instead, we use struct and composition to achieve similar results.
Golang does not support direct inheritance like some other languages. You can achieve it by using he "embedding" that means you can embed one struct inside another struct. This allows the outer struct to use the fields and methods of the inner struct.
Let's go through the examples to have a better idea of this concept −
Composition (Embedding)
The Composition (Embedding) is used to combine structs by embedding one struct inside another(which is similar to inheritance).
Example
In this example, we define a 'Dog' that inherits behavior from 'Animal', allowing it to "speak" using the Speak method, which prints a message by including the dog's name.
package main import "fmt" type Animal struct { Name string } func (a *Animal) Speak() { fmt.Println(a.Name, "makes a sound") } type Dog struct { Animal Breed string } func main() { d := Dog{ Animal: Animal{Name: "Rex"}, Breed: "German Shepherd", } d.Speak() }
Following is the output to the above program −
Rex makes a sound
2. Interface
Interface in Golang is a way to define a set of methods that a type must implement. This allows you to achieve polymorphism, which is another aspect of inheritance.
Example
In this example, we demonstrate polymorphism by assigning a 'Dog' to a 'Speaker' interface and calling the Speak method to display the dog's sound.
package main import "fmt" type Speaker interface { Speak() } type Animal struct { Name string } func (a *Animal) Speak() { fmt.Println(a.Name, "makes a sound") } type Dog struct { Animal Breed string } func main() { var s Speaker d := Dog{ Animal: Animal{Name: "Rex"}, Breed: "German Shepherd", } s = &d s.Speak() }
Following is the output to the above program −
Rex makes a sound
3. Method Overriding
Go does not support method overriding directly, but you can achieve similar behavior by defining methods with the same name on the derived struct.
Example
In the following example, we define an 'Animal' struct with a 'Speak' method, embeds it into a Dog struct, overrides the Speak method in Dog, and call the d.Speak() to print the output as "Rex barks".
package main import "fmt" type Animal struct { Name string } func (a *Animal) Speak() { fmt.Println(a.Name, "makes a sound") } type Dog struct { Animal Breed string } func (d *Dog) Speak() { fmt.Println(d.Name, "barks") } func main() { d := Dog{ Animal: Animal{Name: "Rex"}, Breed: "German Shepherd", } d.Speak() }
Following is the output to the above program −
Rex barks
4. Type Assertion and Type Switching
If you need to access specific methods or fields to a derived type, you can use type assertion or type switching.
Example
In this example, we use polymorphism with the Speaker interface to differentiate between 'Dog' and 'Animal' using type assertion and type switch to print the output.
package main import "fmt" type Speaker interface { Speak() } type Animal struct { Name string } func (a *Animal) Speak() { fmt.Println(a.Name, "makes a sound") } type Dog struct { Animal Breed string } func (d *Dog) Speak() { fmt.Println(d.Name, "barks") } func main() { var s Speaker d := Dog{ Animal: Animal{Name: "Rex"}, Breed: "German Shepherd", } s = &d // Type assertion if dog, ok := s.(*Dog); ok { fmt.Println("Breed:", dog.Breed) } // Type switch switch v := s.(type) { case *Dog: fmt.Println("This is a dog of breed:", v.Breed) case *Animal: fmt.Println("This is an animal named:", v.Name) } }
Following is the output to the above program −
Breed: German Shepherd This is a dog of breed: German Shepherd