Three characteristics of object-oriented programming - inheritance
Why Inheritance:
A small problem, see a system of student test program extends01.go, ask questions of code reuse:
Code:
package main
import (
"fmt"
)
// write a student examination system
//小学生
type Pupil struct {
Name string
Age int
Score int
}
// display his results
FUNC (the p-* Pupil) ShowInfo () {
fmt.Printf ( "the age of the student name =% v =% v score =% v \ n", p.Name , p.Age, p.Score)
}
FUNC (P * Pupil) SetScoure (Score int) {
IF Score <0 || Score> {100
fmt.Println ( "you entered is incorrect grade")
}
p.Score Score =
}
FUNC (P * Pupil) Testing () {
fmt.Println ( "primary examination is ...")
}
//大学生
type Graduate struct {
Name string
Age int
Score int
}
// display his results
FUNC (the p-* Graduate) ShowInfo () {
fmt.Printf ( "the age of the student name =% v =% v score =% v \ n", p.Name , p.Age, p.Score)
}
FUNC (P * Graduate) SetScoure (Score int) {
IF Score <0 || Score> {100
fmt.Println ( "you entered is incorrect grade")
}
p.Score Score =
}
FUNC (the p-* Graduate) Testing () {
fmt.Println ( "college students taking a test in ...")
}
// code redundancy ... high school ....
func main() {
var pupil = &Pupil{
Name : "tom",
Age : 10,
}
pupil.testing()
pupil.SetScoure(90)
pupil.ShowInfo()
var graudate = &Graduate{
Name : "mary",
Age : 20,
}
graudate.testing()
graudate.SetScoure(80)
graudate.ShowInfo()
}
Summary of the above code:
1) fields and methods Pupil and Graduate two structures are almost the same, but we wrote a nearly identical duplicate code, code reusability is not strong.
2) appears redundant code, and the code is not conducive to maintenance, while not conducive to extended functions.
3) Solution - be solved by inheritance
Basic introduction and inheritance diagram:
Inheritance can be solved code reuse, so that our program closer to the human mind.
When there is a plurality of identical structure attributes (fields), and methods, the structure can be abstracted from these structures (such as just Student), these same properties and methods defined in this structure.
Other structures without redefining these attributes (fields) and method, only a nested structure to Student anonymous.
schematic diagram:
In other words: in Golang, if a nested struct another anonymous structure, this structure can directly access the fields and methods of anonymous structures, enabling the inheritance feature.
Anonymous nested structure of the basic syntax:
type Goods struct {
Name string
Price int
}
struct {Book type
Goods // this is a nested structure anonymous Goods
Writer String
}
Getting Started:
We improvements extends01.go, anonymous way to use nested structure to implement inheritance feature, please pay attention to understand the benefits of this program
Code:
package main
import (
"fmt"
)
// write a student examination system
type Student struct {
Name string
Age int
Score int
}
// The Pupil and Graduate common method is bound to Student *
FUNC (STU * Student) ShowInfo () {
fmt.Printf ( "the age of the student name =% v =% v score =% v \ n", stu.Name , stu.Age, stu.Score)
}
FUNC (STU * Student) SetScore (Score int) {
IF Score <0 || Score> {100
fmt.Println ( "you entered is incorrect grade")
}
stu.Score Score =
}
// * Student increased to a method, and then Pupil Graduate can use this method
FUNC (STU * Student) GetSum (int N1, N2 int) {int
return N1 + N2
}
// primary
type struct {Pupil
Student
}
// This is a unique method Pupil structure, retention
FUNC (P * Pupil) Testing () {
fmt.Println ( "primary examination is ...")
}
// Students
of the type struct {Graduate
Student
}
// This is a unique method of Graduate structure to retain
FUNC (the p-* Graduate) Testing () {
fmt.Println ( "college students taking a test in ...")
}
func main() {
// When our team structure embedded in your structures, methods used vary.
pupil: = {} & Pupil
pupil.Student.Name = "Tom ~"
pupil.Student.Age =. 8
pupil.testing ()
pupil.Student.SetScore (70)
pupil.Student.ShowInfo ()
fmt.Println ( "RES = ", pupil.Student.GetSum (1,2))
graduate := &Graduate{}
graduate.Student.Name = "mary"
graduate.Student.Age = 20
graduate.testing()
graduate.Student.SetScore(90)
graduate.Student.ShowInfo()
fmt.Println("res2=", graduate.Student.GetSum(3,4))
}
Inherited depth discussion:
1) structure can use all fields and methods of anonymous nested structure, namely: the first letter in uppercase and lowercase fields, methods, can be used.
案例:
type A struct {
Name string
age int
}
func (a *A) Sayok() {
fmt.Println("A Sayok", a.Name)
}
func (a *A) hello() {
fmt.Println("A hello", a.Name)
}
func (a *A) hello2() {
fmt.Println("A hello", a.age)
}
type B struct {
A
}
func main() {
var b B
b.A.Name = "tom"
b.A.age = 19
b.A.Sayok()
b.A.hello()
b.A.hello2()
}
2) Anonymous Access field structure can be simplified
Case:
FUNC main () {
var b B
b.A.Name = "tom"
b.A.age = 19
b.A.Sayok()
b.A.hello()
b.A.hello2()
// The above wording can be simplified
b.name = "Smith"
b.age = 20 is
b.Sayok ()
b.hello ()
b.hello2 ()
}
Summary of the above code:
(1) when we directly accessed through a field or method b, the implementation process is as follows: For example b.name
(2) look at the compiler will have no corresponding type b Name, if so, a direct call type B Name field
( 3) If you do not go to see B embedded in anonymous structure a has not declared the Name field, if you call, if not continue to find ... if you can not find the error.
3) When the structure and the anonymous structure have the same field or method, the compiler uses the principle of accessing the nearest access, such as access fields and methods of anonymous desired structure, can be distinguished by the structure name anonymous.
案例:
type A struct {
Name string
age int
}
func (a *A) Sayok() {
fmt.Println("A Sayok", a.Name)
}
func (a *A) hello() {
fmt.Println("A hello", a.Name)
}
func (a *A) hello2() {
fmt.Println("A hello", a.age)
}
type B struct {
A
Name string
}
func main() {
var b B
b.Name = "jack"
b.A.Name = "soctt"
b.age = 100
b.Sayok()
b.hello()
}
4) embedded in the structure of two (or more) anonymous structures, such as two anonymous structures and methods have the same field (while the structure itself is not the same name fields and methods), when accessing must explicitly specify anonymous structure name or the compiler error.
Case:
type A struct {
Name string
age int
}
type B struct {
Name string
score float64
}
type C struct {
A
B
}
main FUNC () {
var c C
// if c is not the Name field, and A and B have the Name field, then you must specify the name of the anonymous structure
// so c.Name will report compilation errors, this method is the same rule the
//c.Name = "Tom" // error
CAName = "Tom" // the OK
fmt.Println (C)} // {{Tom 0} {0}
}
5) If a nested struct structure of a well-known, this model is a combination of, if a combination of relationship, when the structure of the field or method in combination access, must bring the name structure.
Case:
type A struct {
Name string
age int
}
D {struct type
A // A nested structure known
}
main FUNC () {
// If D is a well-known structure, the structure of the access field is known, must bring famous structure names
// such daname
var D D
daname = "Jack"
fmt.Println (D )
}
6) After the anonymous nested structure, can also be created when the structure variables (Example), which directly specifies the values of the respective fields anonymous structure.
Case:
type Goods struct {
Name string
Price float64
}
type Brand struct {
Name string
Address string
}
type TV struct {
Goods
Brand
}
type TV2 struct {
*Goods
*Brand
}
main FUNC () {
TV1: the TV = {{Goods "TV 001", 5000}, Brand { " Haier", "Qingdao"}}
TV2: = {the TV
Goods { "002 TV", 5000.99},
Brand { "Siemens", "Beijing"}
}
TV3: = {TV
Goods {
Price: 4000,
the Name: "TV 003"
},
Brand {
the Name: "Sharp"
Address: "Shanghai",
},
}
fmt.Println (tv1)
fmt.Println (TV2)
fmt.Println (TV3)
tv4: = TV2 {& Goods { " TV 004", 7000}, & Brand { " Skyworth", "Henan"},}
TV5: = TV2 {
& Goods {
the Name: "TV 005",
Price: 6000,
},
& Brand {
the Name: "Philips",
the Address: "the Netherlands",
},
}
fmt.Println (tv4.Goods *, * tv4.Brand)
fmt.Println (tv5.Goods *, * tv5.Brand)
}