Many are wondering whether Golang is a language that can apply the Object Oriented Programming paradigm. Let's discuss this here. First of all, we have to know what is meant by Object-Oriented Programming, after that we will try to answer the question of whether GO can implement Object-Oriented Programming. Object-Oriented Programming (OOP) By definition Object Oriented Programming means that this paradigm focuses on objects, objects in a language are made of classes or entities. So by definition, Object-Oriented Programming means an object-focused paradigm.¹ Conceptually, the Object-Oriented Programming paradigm has four main concepts, namely abstraction, encapsulation, inheritance, and polymorphism.² Can GO implement Object-Oriented Programming? Can GO create objects from classes or entities? Let's try to prove it // class or entity or struct type Person struct { // attributes FirstName string LastName string } // method func (p *Person) fullname() string { return p.FirstName + " " + p.LastName } func main() { john := Person{ FirstName: "John", LastName: "Travolta", } fmt.Println(john.fullname()) // John Travolta } The answer is yes, in GO we can create an Object from a class/entity, a class in GO is also called a lightweight struct.³ By definition, GO can apply the Object-Oriented Programming paradigm. What about the main concept of Object-Oriented Programming? This question has caused a lot of debate on "which GO language can implement Object-Oriented Programming or not". Let's discuss the concepts one by one. Abstraction Abstraction is a concept that allows us to hide complexity in the implementation, and only provide information that the user needs or uses. For example, we will create two employee abstractions that will be used by the payroll department and employee managers. The payroll section requires the name and amount of the salary, so the employee abstraction in the payroll package contains only the function which returns how much salary to use. we hide the difficulty of calculating salaries, calculating bonuses, and . GetName CalculateSalary how performance affects bonuses is not required by payroll package payroll // employee abstraction on finance type EmployeeOnPayroll interface { GetName() string CalculateSalary() float64 } func Work(employees ...EmployeeOnPayroll) { for _, employee := range employees { fmt.Println(employee.GetName(), "salary is", employee.CalculateSalary()) } } Likewise, the manager only needs a function to assess performance, so the employee abstraction on the manager's side only contains the function, . SetPerformance no other functions such as CalculateSalary are needed package manager // employee abstraction on manager type EmployeeOnManager interface { SetPerformance(performance employee.Performance) } func Work(employees ...EmployeeOnManager) { for i, employee := range employees { employee.SetPerformance(employee.Performance(i % 3)) } } In our package, the implementation, and all the hassle of calculating salaries and bonuses are . employee hidden from other packages package employee // performance constant type Performance int32 const ( Bad Performance = iota Good Great ) type Employee struct { // attributes Name string BasicSalary float64 performance Performance } // employee method func (e *Employee) GetName() string { return e.Name } func (e *Employee) SetPerformance(performance Performance) { e.performance = performance } func (e *Employee) CalculateSalary() float64 { salary := e.BasicSalary salary += e.calculateBonus() /* Do more calculation */ return salary } func (e *Employee) calculateBonus() float64 { switch e.performance { case Great: return e.BasicSalary case Good: return e.BasicSalary / 2 default: return 0 } } In the main package, we can see how the abstraction we have created works. package main /* imports ... */ func main() { john := &employee.Employee{Name: "John", BasicSalary: 3000} jane := &employee.Employee{Name: "Jane", BasicSalary: 2000} bane := &employee.Employee{Name: "Bane", BasicSalary: 1500} manager.Work(john, jane, bane) payroll.Work(john, jane, bane) /* John salary is 3000 Jane salary is 3000 Bane salary is 3000 */ } Even though John, Jane, and Bane have different base salaries but because of the performance bonus, in the end, they get the same salary. Encapsulation Encapsulation is the concept of how we can protect data or functions on an entity, thus avoiding the wrong use or unwanted data changes. Applying Encapsulation to Golang is quite easy, the use of lowercase in the first letter of naming attributes and methods indicates that the methods and attributes are private (cannot be accessed from outside the package). For example, we can see the attribute (line 15) and the method (line 36) in the employee package. performance calculateBonus package employee // performance constant type Performance int32 const ( Bad Performance = iota Good Great ) type Employee struct { // attributes Name string BasicSalary float64 performance Performance // performance is private attribute } // employee method func (e *Employee) GetName() string { return e.Name } func (e *Employee) SetPerformance(performance Performance) { e.performance = performance } func (e *Employee) CalculateSalary() float64 { salary := e.BasicSalary salary += e.calculateBonus() /* Do more calculation */ return salary } func (e *Employee) calculateBonus() float64 { // caculateBonus is private method switch e.performance { case Great: return e.BasicSalary case Good: return e.BasicSalary / 2 default: return 0 } } Inheritance Inheritance is a concept where we can inherit methods and attributes from an existing class (parent class) to a newly created class (child class). GO does not have Inheritance, but can use Composition as a solution even though it is still different from Inheritance, if Inheritance we can treat child classes as parent classes, while with Composition in GO we have to create interfaces if we want to use parent classes and child classes in the same place. if you wonder why? you can read an article from Rob Pike or Golang FAQ about inheritance . here here Composition in GO is quite easy to do, just add the base struct (parent class) to the newly created struct attribute. For example in line 4, we combine the struct with the struct. The Supervisor automatically gets all the methods and attributes of the Employee. Employee Supervisor package employee type Supervisor struct { Employee // composite Employee to Supervisor SupervisorBonus float64 } // Overriding CalculateSalary function from Employee Struct func (s *Supervisor) CalculateSalary() float64 { salary := s.BasicSalary salary += s.calculateBonus() // add supervisor bonus to salary salary += s.SupervisorBonus /* Do more calculation */ return salary } Because it gets all the methods and attributes of the , the can be directly used in the and interfaces. Employee Supervisor EmployeeOnManager EmployeeOnPayroll package main /* imports ... */ func main() { john := &employee.Employee{Name: "John", BasicSalary: 3000} jane := &employee.Supervisor{ Employee: employee.Employee{Name: "Jane", BasicSalary: 2000}, SupervisorBonus: 500, } bane := &employee.Employee{Name: "Bane", BasicSalary: 1500} manager.Work(john, jane, bane) payroll.Work(john, jane, bane) /* John salary is 3000 Jane salary is 3500 Bane salary is 3000 */ } Polymorphism Polymorphism consists of two words, namely Poly which means many, and Morph which means form. Usually, in Object-Oriented Programming, there are two ways to apply Polymorphism, namely Overloading and Overriding. Overloading allows a class to have methods with the same name but have different parameters or return parameters. Overriding allows the child class to have the same method (name, parameter, and return parameters) as the parent class but with a different implementation, when the method is called, the implementation of the child class will be used. Golang can apply Overriding, but cannot apply Overloading. Why? You can read the explanation in GO FAQ . here The implementation of overriding in GO is similar to Java or Javascript. After we do the composition for the child class we can create a method in the child class with the same name, parameters, and return parameters as the method we want to override. For example, the method on the struct on line 9. The actually already has a method obtained from the struct, but we need to override it because there are different ways of calculating. CalculateSalary Supervisor Supervisor CalculateSalary Employee package employee type Supervisor struct { Employee // composite Employee to Supervisor SupervisorBonus float64 } // Overriding CalculateSalary function from Employee Struct func (s *Supervisor) CalculateSalary() float64 { salary := s.BasicSalary salary += s.calculateBonus() // add supervisor bonus to salary salary += s.SupervisorBonus /* Do more calculation */ return salary } With overriding, Jane's salary calculation result changed from 3000 to 3500, because was added to her salary. SupervisorBonus package main /* imports ... */ func main() { john := &employee.Employee{Name: "John", BasicSalary: 3000} jane := &employee.Supervisor{ Employee: employee.Employee{Name: "Jane", BasicSalary: 2000}, SupervisorBonus: 500, } bane := &employee.Employee{Name: "Bane", BasicSalary: 1500} manager.Work(john, jane, bane) payroll.Work(john, jane, bane) /* John salary is 3000 Jane salary is 3500 Bane salary is 3000 */ } Conclusion So is Golang an object-oriented programming language? I will quote two versions of the answer. , GO is Object-Oriented, but in an unusual way.⁴ Yes , although Go has types and methods, and allows "style" Object-Oriented Programming, but GO does not have a hierarchy (inheritance). The GO “interface” concept (because it uses Composition, not Inheritance) provides a different approach that GO's creators believe is easier to use in more general terms.⁵ Yes and No References ¹__ __ ²__ __ ³__ __ ⁴__ __ ⁵__ __ https://www.javatpoint.com/what-is-object-oriented-programming https://www.freecodecamp.org/news/object-oriented-programming-concepts-21bb035f7260/ https://www.geeksforgeeks.org/structure-equality-in-golang/ https://talks.golang.org/2012/chat.slide#5 https://go.dev/doc/faq#Is_Go_an_object-oriented_language Thank you for reading, hopefully, it will be useful for all of us, and we can learn together to be better. If you have questions or want to share or discuss, you can go through the comments column or through my contact on my profile 😁 Also Published here