Object-oriented programming

Go is designed to be very simple and elegant for object-oriented programming. The neat thing is that the Go language does not inherit many of the concepts of traditional object-oriented programming, such as inheritance, virtual functions, constructors and destructors, the hidden this pointer, and so on. The beauty is that Go’s support for object-oriented programming is a natural part of the language type system, which flows together through interfaces.

The type system

Other languages have little knowledge of type systems, and in fact type languages are the foundation of a programming language, and their importance is undeniable.

As the name implies, a type system refers to the type architecture of a language. A typical type system usually contains the following basics:

  • Basic types such as byte, int, bool, float, and so on
  • Compound types, such as groups, structures, Pointers, and so on
  • A type that can point to Any object (type Any)
  • Value semantics and reference semantics
  • Object oriented, that is, all types that have object-oriented characteristics, such as member methods
  • interface

Java language since its birth is known as the most pure object-oriented language, there are two sets of independent type system in Java language, one is the value type system, mainly basic types, such as byte, int, Boolean, char, double and so on. A set of Object type system based on the Object type as the root, these types can be member variables and member methods, is based on reference semantics, only allowed to create on the heap, Java has a kind of everything Object saying, can understand Object is the parent of all classes, we will use the method in the Object class when using the class.

By contrast, most types in the Go language have value semantics and can contain corresponding operation methods. You can “add” new methods to any type (including built-in types) as needed. When you implement an interface, you don’t need to inherit from the interface. You just need to implement all the methods required by the interface. Any type can be referenced by Any type. The Any type is an empty interface, interface{}.

Add methods for classes

In Go, you can add methods to any type (including built-in types, but not pointer types) as follows:

type Integer int
func (a Integer) Less(b Integer) bool { 
    return a < b 
}
Copy the code

A new type Integer is defined that is not fundamentally different from int except that it adds a new method Less() to the built-in int type. But to be honest I was a little confused about what the point was, you know? Once you implement an Integer, you can use an Integer just like a normal class, right?

func main() { 
var a Integer = 1 
if a.Less(2) { 
 fmt.Println(a, "Less 2") 
 } 
}
Copy the code

If the Integer example above were implemented in a procedural way instead of using the object-oriented features of the Go language, the corresponding implementation details would look like this:

type Integer int
func Integer_Less(a Integer, b Integer) bool { 
    return a < b 
} 
func main() { 
    var a Integer = 1 
    if Integer_Less(a, 2) { 
         fmt.Println(a, "Less 2") 
     } 
}
Copy the code

In Go, the object-oriented mystique is stripped clean. Compare the following two pieces of code:

Func (a Integer) Less(b Integer) bool {// Object-oriented return a < b} func Integer_Less(a Integer, B Integer) bool {// Process-oriented return A < b} a. less (2) // Object-oriented usage Integer_Less(a, 2) // Process-oriented usageCopy the code

Object orientation is just another syntactic expression. One of the things that confuses some people about object orientation in C++ is the hidden this pointer. Once the hidden this pointer is exposed, you see procedural programming.

There is no hidden pointer to this in the Go language.

  • Methods impose targets (that is, “objects”) that are passed explicitly and not hidden
  • The target (” object “) imposed by a method does not have to be a pointer, nor does it have to be called this

Code like Java

class Integer { private int val; public boolean Less(Integer b) { return this.val< b.val; }}Copy the code

If you don’t understand where this.val comes from at first glance, this code might be easier to understand if you write a procedural c implementation like this:

struct Integer { 
    int val; 
}; 
bool Integer_Less(Integer* this, Integer* b) { 
return this->val < b->val; 
}
Copy the code

As you can see, the Java code hides Integer* this, the first argument to the Integer class method Less(), and the C implementation displays Integer* this.

If an object needs to be modified, it must be passed by a pointer, which is not a Go language constraint but a natural one. As follows:

func (a *Integer) Add(b Integer) { 
 *a += b 
}
Copy the code

The Integer type adds the Add() method, which modifies the value of the object and must be referenced by a pointer

func main() { 
    var a Integer = 1 
    a.Add(2) 
    fmt.Println("a =", a) 
}
Copy the code

The result is a = 3, which changes the reference of the object, if the reference is not passed, but the value is passed

func (a Integer) Add(b Integer) {
    a += b
}
Copy the code

When I run the program, I get a = 1, which is the same value as before. The reason for this is that Go, like C, is based on value passing. To change the value of a variable, only Pointers can be passed. If the value is passed the original value will not be modified! Java intermediate value passing can be thought of as copying the same value. Operations on it do not affect the value of a before copying, so the value of A remains unchanged.

conclusion

Summarize the Go language object-oriented programming, abandoned the complicated implementation of other languages, only use the implementation of all the interface methods, summed up the difference between value passing and reference passing.

note

Master I quickly insist not to live good sleepy !!!! Go to bed. Bye!

This article is participating in the “Nuggets Golang Theme Learning Month”. Click here for more details.