Introduction to Polymorphism in Go

Welcome to the lesson on Polymorphism with Go. Polymorphism, an essential pillar of object-oriented programming (OOP), enables us to design versatile, legible, and modular code that promotes code reuse. In this lesson, you will understand Polymorphism and its implementation in Go.

Understanding Polymorphism

The marvel of Polymorphism lies in its ability to treat different data types as identical forms, thus simplifying your code and boosting its extensibility.

Consider the management of a zoo that houses various animals, such as Tigers, Elephants, and Monkeys. Each animal type exhibits specific behaviors but shares common features like eating, thereby demonstrating Polymorphism.

Achieving Polymorphism in Go

Polymorphism in Go is implemented using Interfaces — a sophisticated collection of method signatures that allow different entities to follow standard interactions.

We demonstrate this with an example featuring the Shape interface and two structs — Circle and Rectangle.

package main

import (
    "fmt"
    "math"
)

// Shape interface declaration
type Shape interface {
    Area() float64
}

// Circle struct declaration
type Circle struct {
    radius float64
}

// Rectangle struct declaration
type Rectangle struct {
    width, height float64
}

// Implementing the Area method for Circle
func (c Circle) Area() float64 {
    return math.Pi * c.radius * c.radius
}

// Implementing the Area method for Rectangle
func (r Rectangle) Area() float64 {
    return r.width * r.height
}

func main() {
    circle := Circle{2}
    rectangle := Rectangle{3, 4}
    fmt.Printf("Area of Circle: %f\n", circle.Area())  //prints "Area of Circle: 12.566371"
    fmt.Printf("Area of Rectangle: %f\n", rectangle.Area()) //prints "Area of Rectangle: 12.000000"
}

Here, both Circle and Rectangle implement the Area method. Thus, wherever a Shape is expected, a Circle or Rectangle can be used interchangeably.

Demonstrating Polymorphism with an Example

Let's exemplify Polymorphism using a zoo simulator that houses Dogs, Cats, and Birds. We aim to hear each animal's unique sound.

package main

import (
    "fmt"
)

// Animal interface declaration
type Animal interface {
    Sound() string
}

// Dog struct declaration
type Dog struct{}

// Cat struct declaration
type Cat struct{}

// Bird struct declaration
type Bird struct{}

// Implementing the Sound method for Dog
func (d Dog) Sound() string {
    return "Woof!"
}

// Implementing the Sound method for Cat
func (c Cat) Sound() string {
    return "Meow!"
}

// Implementing the Sound method for Bird
func (b Bird) Sound() string {
    return "Tweet!"
}

func makeSound(a Animal) {
    fmt.Println(a.Sound())
}

func main() {
    dog := Dog{}
    cat := Cat{}
    bird := Bird{}
    
    makeSound(dog)    //prints "Woof!"
    makeSound(cat)    //prints "Meow!"
    makeSound(bird)   //prints "Tweet!"
}

Here, the Dog, Cat, and Bird structs implement the Animal interface. This exemplifies Polymorphism, as makeSound works with any Animal and prints the animal's unique sound.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal