Is Go an object-oriented language?

Technology CommunityCategory: GolangIs Go an object-oriented language?
VietMX Staff asked 3 years ago

Yes and no. Although Go has types and methods and allows an object-oriented style of programming, there is no type hierarchy. This is in contrast to most object-oriented languages like C++, Java, C#, Scala, and even dynamic languages like Python and Ruby.

Go Object-Oriented Language Features:

  • Structs – Structs are user-defined types. Struct types (with methods) serve similar purposes to classes in other languages.
  • Methods – Methods are functions that operate on particular types. They have a receiver clause that mandates what type they operate on.
  • Embedding – we can embed anonymous types inside each other. If we embed a nameless struct then the embedded struct provides its state (and methods) to the embedding struct directly.
  • Interfaces – Interfaces are types that declare sets of methods. Similarly to interfaces in other languages, they have no implementation. Objects that implement all the interface methods automatically implement the interface. There is no inheritance or subclassing or “implements” keyword.

The Go way to implement:

  • Encapsulation – Go encapsulates things at the package level. Names that start with a lowercase letter are only visible within that package. You can hide anything in a private package and just expose specific types, interfaces, and factory functions.
  • Inheritance – composition by embedding an anonymous type is equivalent to implementation inheritance.
  • Polymorphism – A variable of type interface can hold any value which implements the interface. This property of interfaces is used to achieve polymorphism in Go.

Consider:

package main

import (  
    "fmt"
)

// interface declaration
type Income interface {  
    calculate() int
    source() string
}

// struct declaration
type FixedBilling struct {  
    projectName string
    biddedAmount int
}

type TimeAndMaterial struct {  
    projectName string
    noOfHours  int
    hourlyRate int
}

// interface implementation for FixedBilling
func (fb FixedBilling) calculate() int {  
    return fb.biddedAmount
}

func (fb FixedBilling) source() string {  
    return fb.projectName
}

// interface implementation for TimeAndMaterial
func (tm TimeAndMaterial) calculate() int {  
    return tm.noOfHours * tm.hourlyRate
}

func (tm TimeAndMaterial) source() string {  
    return tm.projectName
}

// using Polymorphism for calculation based 
// on the array of variables of interface type 
func calculateNetIncome(ic []Income) {  
    var netincome int = 0
    for _, income := range ic {
        fmt.Printf("Income From %s = $%d\n", income.source(), income.calculate())
        netincome += income.calculate()
    }
    fmt.Printf("Net income of organisation = $%d", netincome)
}

func main() {  
    project1 := FixedBilling{projectName: "Project 1", biddedAmount: 5000}
    project2 := FixedBilling{projectName: "Project 2", biddedAmount: 10000}
    project3 := TimeAndMaterial{projectName: "Project 3", noOfHours: 160, hourlyRate: 25}
    incomeStreams := []Income{project1, project2, project3}
    calculateNetIncome(incomeStreams)
}