Polymorphism is a fundamental concept in object-oriented programming (OOP) that allows objects of different types to be treated as instances of a common superclass or to respond to the same interface. While Go does not support class-based inheritance, it provides mechanisms to achieve polymorphism through interfaces.
In Go, you can define interfaces that specify a set of method signatures. Any type that implements all the methods defined in an interface is said to satisfy or implement that interface. This allows for polymorphic behaviour in Go, where different types can be treated interchangeably based on their shared interface.
Here’s an example that demonstrates polymorphism in Go using interfaces:
package main
import "fmt"
type Animal interface {
Sound() string
}
type Dog struct{}
func (d Dog) Sound() string {
return "Woof!"
}
type Cat struct{}
func (c Cat) Sound() string {
return "Meow!"
}
func MakeSound(a Animal) {
fmt.Println(a.Sound())
}
func main() {
d := Dog{}
c := Cat{}
MakeSound(d)
MakeSound(c)
}
In this example, we define an Animal
interface that specifies a single method Sound()
, which returns a string. The Dog
and Cat
types implement the Animal
interface by defining the Sound()
method.
The MakeSound()
function takes an Animal
parameter and calls the Sound()
method on it. This function can accept any type that satisfies the Animal
interface, allowing us to pass Dog
and Cat
instances interchangeably.
In the main()
function, we create a Dog
instance d
and a Cat
instance c
. We then invoke the MakeSound()
function with d
and c
as arguments. Since both Dog
and Cat
implement the Animal
interface, they can be treated as Animal
instances, and their respective Sound()
methods are called.
When we run the program, the output will be:
Woof!
Meow!
Through interfaces, Go enables polymorphism by allowing different types to be treated interchangeably based on their shared interface. This promotes loose coupling, flexibility, and code reusability.
Polymorphism using an interface in Go
Polymorphism in Go is achieved through interfaces. Interfaces define a set of method signatures, and any type that implements all the methods specified in an interface is said to satisfy that interface. This allows different types to be treated interchangeably based on their shared interface, enabling polymorphic behavior.
Here’s an example that demonstrates polymorphism using an interface in Go:
package main
import "fmt"
type Shape interface {
Area() float64
}
type Rectangle struct {
Width float64
Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
func PrintArea(s Shape) {
fmt.Printf("Area: %.2f\n", s.Area())
}
func main() {
r := Rectangle{Width: 3, Height: 4}
c := Circle{Radius: 2.5}
PrintArea(r)
PrintArea(c)
}
In this example, we define an Shape
interface with a single method Area()
that returns a float64
value. The Rectangle
and Circle
types implement the Shape
interface by providing their own implementations of the Area()
method.
The PrintArea()
function takes an Shape
parameter and calls the Area()
method on it. It can accept any type that satisfies the Shape
interface, allowing us to pass Rectangle
and Circle
instances interchangeably.
In the main()
function, we create a Rectangle
instance r
and a Circle
instance c
. We invoke the PrintArea()
function with r
and c
as arguments. Since both Rectangle
and Circle
implement the Shape
interface, they can be treated as Shape
instances, and their respective Area()
methods are called.
When we run the program, the output will be:
Area: 12.00
Area: 19.63
Through the use of interfaces, Go achieves polymorphism by allowing different types to be treated interchangeably based on their shared interface. This promotes code reusability, modularity, and flexibility, allowing you to write more generic and reusable code.