Go Inheritance
In object-oriented programming (OOP), inheritance is a mechanism that allows a class (subclass) to inherit properties and methods from another class (parent class). Through inheritance, subclasses can reuse code from the parent class and extend or modify its behavior without modifying the parent class.
Go is not a traditional object-oriented programming language; it does not have concepts of classes and inheritance.
Go uses structs and interfaces to achieve similar functionality.
* * *
## "Inheritance" in Go
Go does not have class and inheritance concepts found in traditional object-oriented languages, but instead achieves similar functionality through composition and interfaces.
### 1. Composition
Composition is the primary way to achieve code reuse in Go. By embedding one struct into another, the child struct can "inherit" the fields and methods of the parent struct.
## Example
package main
import"fmt"
// Parent struct
type Animal struct{
Name string
}
// Method of parent struct
func(a *Animal) Speak(){
fmt.Println(a.Name,"says hello!")
}
// Child struct
type Dog struct{
Animal // Embed Animal struct
Breed string
}
func main(){
dog := Dog{
Animal: Animal{Name:"Buddy"},
Breed:"Golden Retriever",
}
dog.Speak()// Call method of parent struct
fmt.Println("Breed:", dog.Breed)
}
#### Code Explanation
* `Animal` is the parent struct, containing a field `Name` and a method `Speak`.
* `Dog` is the child struct, which inherits `Animal`'s fields and methods by embedding the `Animal` struct.
* In the `main` function, we create a `Dog` instance and call the `Speak` method.
* * *
### 2. Interface
Interface is the primary way to achieve polymorphism in Go. By defining interfaces, different structs can implement the same methods, thereby achieving polymorphic behavior similar to inheritance.
#### Example Code
## Example
package main
import"fmt"
// Define interface
type Speaker interface{
Speak()
}
// Parent struct
type Animal struct{
Name string
}
// Implement interface method
func(a *Animal) Speak(){
fmt.Println(a.Name,"says hello!")
}
// Child struct
type Dog struct{
Animal
Breed string
}
func main(){
var speaker Speaker
dog := Dog{
Animal: Animal{Name:"Buddy"},
Breed:"Golden Retriever",
}
speaker =&dog
speaker.Speak()// Call method through interface
}
#### Code Explanation
* `Speaker` is an interface that defines a `Speak` method.
* The `Animal` struct implements the `Speaker` interface.
* The `Dog` struct indirectly implements the `Speaker` interface by embedding the `Animal` struct.
* In the `main` function, we assign the `Dog` instance to the `Speaker` interface and call the `Speak` method through the interface.
### Differences Between Go and Classic Inheritance
| Feature | Classic Inheritance | Go's Approach |
| --- | --- | --- |
| Code Reuse | Through inheritance | Through composition (embedding structs) |
| Polymorphism | Through inheritance and method overriding | Through interface implementation |
| Relationship | "Is-a" relationship | "Has-a" or "implements" relationship |
| Flexibility | Fixed inheritance relationship | Can compose at runtime |
**Complete Inheritance Simulation:**
## Example
package main
import"fmt"
// Base class
type Vehicle struct{
Brand string
}
func(v *Vehicle) Start(){
fmt.Println(v.Brand,"started")
}
// Derived class
type Car struct{
Vehicle // Embed Vehicle
Model string
}
// Override Start method
func(c *Car) Start(){
fmt.Println(c.Brand, c.Model,"car started")
}
func main(){
v := Vehicle{Brand:"Toyota"}
c := Car{
Vehicle: Vehicle{Brand:"Honda"},
Model:"Civic",
}
v.Start()// Toyota started
c.Start()// Honda Civic car started
c.Vehicle.Start()// Honda started
}
Go's design avoids many problems of traditional inheritance, such as the fragile base class problem, while providing greater flexibility.
YouTip