This is a creation in Article, where the information may have evolved or changed.
Overall, the go language object-oriented in the use of the way is flexible and easy, can say that the design concept is really advanced, so that people have a feeling like mu Spring breeze.
If you have experienced a learning process from C to C + + in your student life, do you still remember that the teacher would say that C + + is object-oriented, so we don't have to use structs in C as data structures. We only need to define the classes in C + + because there are no member properties in the class, and there are member functions. In other words, class is a perfect alternative to structs and more powerful.
Back to go, our object-oriented use is struct , but the times are different, this time our struct can also have a "member function."
Define a typical object-oriented approach
package mainimport "fmt"type Human struct { height float32 weight int}func (h Human) BMIindex() (index int){ index = h.weight / int(h.height * h.height) return}func main() { person := Human{1.83, 75} fmt.Printf("this person's height is %.2f m\n", person.height) fmt.Printf("this person's weight is %d kg\n", person.weight) fmt.Printf("this person's BMI index is %d\n", person.BMIindex())}
In the main function we initialized a human object, read their property height and weight, and finally called the human object's member function Bmiindex () and obtained the person's "BMI" by calculation.
Receiver
In the example above, the member function of a human object is defined by receiver. We add receiver to a normal func (the H Human in the above example), which makes up a method bmiindex (). In this case, this function can only rely on a human object to function, not be called independently. The correct way to call is the person above. Bmiindex ()
In another example, we want to change the member properties of an object by defining a member function.
package mainimport "fmt"type Human struct { height float32 weight int}func (h Human) BMIindex() (index int){ index = h.weight / int(h.height * h.height) return}func (h Human) setHeight(height float32) { h.height = height}func main() { person := Human{1.83, 75} fmt.Printf("this person's height is %.2f m\n", person.height) fmt.Printf("this person's weight is %d kg\n", person.weight) fmt.Printf("this person's BMI index is %d\n", person.BMIindex()) person.setHeight(1.90) fmt.Printf("this person's height is %.2f m\n", person.height)}输出结果: this person's height is 1.83 m this person's weight is 75 kg this person's BMI index is 25 this person's height is 1.83 m
As you can see, after we call Person.setheight (1.90), the height property of the person does not change to 1.90. To solve this problem, we need to change receiver. We define the SetHeight () function in the following form.
func (h *Human) BMIindex() (index int){ index = h.weight / int(h.height * h.height) return}
Reason: We use the object 指针类型 as receiver to change the value of its properties. In essence, we can think of receiver as a unique parameter of func. If you are passing an object type, then the function is actually a copy of the object, and if you pass a pointer type, the object itself is changed.
With regard to receiver selection, you can understand that if you need to get an object property (get), you use the object as receiver, and if you need to change the object properties (set), select the pointer as receiver.
Application scope of method
In the above example, the method we define is the one that corresponds to the struct, but the definition of method can depend on all of them 自定义类型 . The so-called custom type is the new type defined by the type statement that gives some built-in types an "alias".
package mainimport "fmt"type Sex stringfunc (s *Sex) change(){ if *s == Sex("女") { *s = Sex("男") }}func main() { sex := Sex("女") fmt.Println("previous sex is ", sex) sex.change() fmt.Println("current sex is ", sex) }
Here, we define a new type of sex and define a method change () for it.
Inheritance in object-oriented
package mainimport "fmt"type Human struct { height float32 weight int}type Woman struct { Human sex string}func (h Human) BMIindex() (index int){ index = h.weight / int(h.height * h.height) return}func main() { woman := Woman{Human{1.65, 50}, "女"} fmt.Printf("this woman's height is %.2f m\n", woman.height) fmt.Printf("this woman's wight is %d kg\n", woman.weight) fmt.Printf("this woman's BMIindex is %d\n", woman.BMIindex())}
This example shows the succession of woman to human. Human is included in the woman struct 匿名字段 , the Human contains attributes that belong to a woman object, and the method of the Human object can also be used by the woman object. It is important to note that this method can be used 重写 . To define only one bmiindex () with the woman object type receiver, call woman again. Bmiindex, the function that is actually called is the newly defined function. This is the rewrite of the method.
Accessing properties
If you are familiar with the access attributes in the object, you must know that public, private, and protected act as access modifiers. And in the go language, we use 大小写 to differentiate.
The first letter of the identifier is capitalized, equivalent to the public property. Such a member property or member function can be 包外部 called in. such as the above woman, Bmiindex.
The first letter of the identifier is lowercase, equivalent to the protected property. Such member properties or member functions can only be 包内部 used.