We know that there is no Class in Go, but that doesn’t mean the language doesn’t support object-oriented programming. After all, object-oriented programming is just a programming idea.

Let’s recall three basic characteristics of object orientation:

  1. Encapsulation: Hides the properties and implementation details of an object and provides only public access
  2. Inheritance: to make a subclass have attributes and methods of its parent class or to redefine, append attributes and methods, etc
  3. Polymorphism: Different implementations of the same behavior in different objects

Let’s take a look at how the Go language implements these three features without classes.

encapsulation

“Class”

In Go, attributes can be encapsulated using Structs, which are like a simplified form of a class.

For example, if we want to define a rectangle, each rectangle has a length and a width, we can encapsulate it like this:

type Rectangle struct {
	Length int
	Width int
}
Copy the code

methods

Now that you have a class, you might ask, where are the methods of a class?

Go also has Methods: A Go method is a function on a receiver, which is a variable of some type. Methods are therefore a special type of function.

The format for defining methods is as follows:

func (recv receiver_type) methodName(parameter_list) (return_value_list){... }Copy the code

Now that we’ve defined a Rectangle, we’ll define a method called Area() to calculate its Area:

package main

import (
	"fmt"
)

// Rectangle structure
type Rectangle struct {
	Length int
	Width  int
}

// Calculate the rectangle area
func (r *Rectangle) Area(a) int {
	return r.Length * r.Width
}

func main(a) {
	r := Rectangle{4.2}
	// Call the Area() method to calculate the Area
	fmt.Println(r.Area())
}
Copy the code

The code snippet above outputs 8.

Access permissions

We often say whether a class’s attributes are public or private. In other programming languages, we use the public and private keywords to express such access.

There are no access control modifiers such as public, private, or protected in the Go language; it controls visibility by letter case.

If the names of defined constants, variables, types, interfaces, structures, functions, etc., begin with an uppercase letter, that means they can be accessed or called by other packages (equivalent to public); Non-uppercase starts can only be used within packages (equivalent to private).

Access unexported fields

How do we access unexported fields that can only be used within a package?

Like other object-oriented languages, Go has a way of implementing getters and setters:

  • forsetterMethods usingSetThe prefix
  • forgettermethodsUse only member names

For example, we now have a Person structure in the Person package:

package person

type Person struct {
	firstName string
	lastName  string
}
Copy the code

We can see that both of its member variables start with a non-uppercase letter and can only be used within the package. Now we define the setter and getter for firstName:

/ / get firstName
func (p *Person) FirstName(a) string {
	return p.firstName
}

/ / set the firstName
func (p *Person) SetFirstName(newName string) {
	p.firstName = newName
}
Copy the code

This way, we can set and get firstName in the main package:

package main

import (
	"fmt"

	"./person"
)

func main(a) {
	p := new(person.Person)
	p.SetFirstName("firstName")
	fmt.Println(p.FirstName())
}

/* Output:
firstName
*/
Copy the code

inheritance

There is no extends keyword in the Go language; it uses methods to implement inheritance by embedding anonymous types in structures.

Anonymous types: that is, these types do not have explicit names.

Methods on an embedded structure can be called directly on an instance of the outer type:

package main

import (
	"fmt"
	"math"
)

type Point struct {
	x, y float64
}

func (p *Point) Abs(a) float64 {
	return math.Sqrt(p.x*p.x + p.y*p.y)
}

type NamedPoint struct {
	Point
	name string
}

func main(a) {
	n := &NamedPoint{Point{3.4}, "Pythagoras"}
	fmt.Println(n.Abs()) / / print 5
}
Copy the code

polymorphism

In object oriented, polymorphism is characterized by different implementations of the same behavior in different objects. This feature can be implemented in the Go language using interfaces.

Let’s first define a Square and a Rectangle:

/ / square
type Square struct {
	side float32
}

/ / rectangle
type Rectangle struct {
	length, width float32
}
Copy the code

And then we want to be able to figure out the areas of these two geometries. But since they calculate the Area differently, we need to define two different Area() methods.

Shaper = Shaper = Shaper = Shaper = Shaper = Shaper = Shaper = Shaper = Shaper = Shaper = Shaper = Shaper;

/ / interface Shaper
type Shaper interface {
	Area() float32
}

// Calculate the area of the square
func (sq *Square) Area(a) float32 {
	return sq.side * sq.side
}

// Calculate the area of a rectangle
func (r *Rectangle) Area(a) float32 {
	return r.length * r.width
}
Copy the code

We can call Area() in main() like this:

func main(a) {
	r := &Rectangle{10.2}
	q := &Square{10}

	// Create an array of type Shaper
	shapes := []Shaper{r, q}
	// Iterate over each element of the array and call the Area() method
	for n, _ := range shapes {
		fmt.Println("Graphic data:", shapes[n])
		fmt.Println("Its area is:", shapes[n].Area())
	}
}

/*Output: &{10 2} Its area is: 20 graphics data: &{10} its area is: 100 */
Copy the code

From the above code output results, we can see that different objects call the Area() method to produce different results, showing the characteristics of polymorphism.

conclusion

  • The three main characteristics of object orientation are encapsulation, inheritance and polymorphism
  • The Go language encapsulates properties with constructs, which are like a simplified form of a class
  • In Go, methods act on the receiver (receiverThe receiver is a variable of some type
  • The case of the first letter of the name determines the variable/constant/type/interface/structure/function… Can be imported by external packages
  • Fields that cannot be imported can be usedgettersetterTo access
  • The Go language implements inheritance by embedding anonymous types in structures
  • Polymorphisms can be implemented using interfaces

The resources

  • Get Started with Go:Github.com/unknwon/the…

Review past

  • Simple to understand: take 🌰 to interpret source code, inverse code and complement code
  • Learn about arrays in Go
  • Talk about character representation and string traversal in Go

🐱

If you think the article is well written, please do me two small favors:

  1. Like and follow me to get this article seen by more people
  2. Pay attention to the public number “programming to save the world”, the public number focuses on programming foundation and server research and development, you will get the first time the new article push ~

Original is not easy, great encouragement ~ thank you!