Encapsulation in Go

Encapsulation in Go

In this tutorial we will discuss encapsulation in Go language. Encapsulation is one of the fundamentals of OOP (object-oriented programming).

Encapsulation may also refer to a mechanism of restricting the direct access to some components of an object, such that users cannot access state values for all of the variables of a particular object.

Encapsulation can be used to hide both data members and data functions or methods associated with an instantiated class or object.

Encapsulation in Go

Encapsulation, as known as information hiding, is a crucial aspect of object-oriented programming. Go being different from classical OOP languages. It doesn’t have a concept of classes, objects & access modifiers in it. Instead, it has a concept of package.

Golang provides encapsulation at the package level. Go doesn’t have any public, private, or protected keyword. The only mechanism to control the visibility is using the capitalized and non-capitalized formats.

  • Capitalized Identifiers are exported. The capital letter indicates that this is an exported identifier.
  • Non-capitalized identifiers are not exported. The lowercase indicates that the identifier is not exported and will only be accessed from within the same package.

There are five kinds of identifier which can be exported or non-exported

  1. Structure
  2. Structure’s Method
  3. Structure’s Field
  4. Function
  5. Variable

Let’s see an example that shows exporting and non-exporting of all the above identifiers. See data.go below. The package is a model.

  • Structure
    • Struct Person is exported
    • Struct company is non-exported
  • Structure’s Method
    • Person Struct’s Method GetAge() is exported
    • Person Struct’s Method getName() is not exported
  • Structure’s Field
    • Person struct field Name is exported
    • Person struct field age is not exported
  • Function
    • Function GetPerson() is exported
    • Function getCompanyName() is not exported
  • Variables
    • Variable CompanyName is exported
    • Variable companyLocation is not exported
package model

import "fmt"

var (
	//CompanyName represents the company name
	CompanyName     = "OpsRamp"
	companyLocation = "Hyderabad"
)

//Person struct
type Person struct {
	Name string
	age  int
}

//GetAge of person
func (p *Person) GetAge() int {
	return p.age
}

func (p *Person) getName() string {
	return p.Name
}

type company struct {
}

//GetPerson get the person object
func GetPerson() *Person {
	p := &Person{
		Name: "Ashok Kumar",
		age:  30,
	}
	fmt.Println("Model Package:")
	fmt.Println(p.Name)
	fmt.Println(p.age)
	return p
}

func getCompanyName() string {
	return CompanyName
}

Let’s write a file test.go in the model package. See below.

package model

import "fmt"

//Test function
func Test() {
	//STRUCTURE IDENTIFIER
	p := &Person{
		Name: "Ashok Kumar",
		age:  30,
	}
	fmt.Println(p)
	c := &company{}
	fmt.Println(c)

	//STRUCTURE'S METHOD
	fmt.Println(p.GetAge())
	fmt.Println(p.getName())

	//STRUCTURE'S FIELDS
	fmt.Println(p.Name)
	fmt.Println(p.age)

	//FUNCTION
	person2 := GetPerson()
	fmt.Println(person2)
	companyName := getCompanyName()
	fmt.Println(companyName)

	//VARIBLES
	fmt.Println(companyLocation)
	fmt.Println(CompanyName)
}

On running this file, it can access all exported and unexported fields in data.go as both lies in the same package model. There is no compilation error, and it gives the below output.

Output

&{Ashok Kumar 30}
&{}
30
Ashok Kumar
Ashok Kumar
30
Model Package:
Ashok Kumar
30
&{Ashok Kumar 30}
OpsRamp
Hyderabad
OpsRamp

Let’s move the above file test.go to a different package named view. Now notice the output on running ‘go build’. It gives compilation errors. All the compilation errors are due to not able to refer to unexported fields.

package view

import "fmt"

//Test function
func Test() {
	//STRUCTURE IDENTIFIER
	p := &Person{
		Name: "Ashok Kumar",
		age:  30,
	}
	fmt.Println(p)
	c := &company{}
	fmt.Println(c)

	//STRUCTURE'S METHOD
	fmt.Println(p.GetAge())
	fmt.Println(p.getName())

	//STRUCTURE'S FIELDS
	fmt.Println(p.Name)
	fmt.Println(p.age)

	//FUNCTION
	person2 := GetPerson()
	fmt.Println(person2)
	companyName := getCompanyName()
	fmt.Println(companyName)

	//VARIBLES
	fmt.Println(companyLocation)
	fmt.Println(CompanyName)
}

Output

test.go:13:3: unknown field 'age' in struct literal of type model.Person
test.go:17:8: cannot refer to unexported name model.company
test.go:17:8: undefined: model.company
test.go:22:15: p.getName undefined (cannot refer to unexported field or method model.(*Person).getName)
test.go:26:15: p.age undefined (cannot refer to unexported field or method age)
test.go:31:17: cannot refer to unexported name model.getCompanyName
test.go:31:17: undefined: model.getCompanyName
test.go:35:14: cannot refer to unexported name model.companyLocation
test.go:35:14: undefined: model.companyLocation

So when working on Go, it is essential to understand how to hide and provide access to data from packages.

Encapsulation in Go
Scroll to top