Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
333 lines (255 sloc) 9.61 KB

More meth(odes) please!

We have learned how to write methods in Go, that they can be seen as functions with an implicit first parameter that is its receiver, and we saw some facilities that Go offers when working with pointers and receivers.

In this chapter we will see how to implement some OOP concepts using methods. It will be fun and relatively easy.

Structs with anonymous fields

I didn't tell you about this when we studied structs, but we actually can declare fields without specifying names for them (just the type). It is for this reason that we call them anonymous fields (the lack of a name).

When an anonymous field is a struct its fields are inserted (embedded) into the struct containing it.

Let's see an example to help clarify this concept:

Output:

His name is Mark
His age is 25
His weight is 120
His speciality is Computer Science
Mark changed his speciality
His speciality is AI
Mark become old
His age is 46
Mark is not an athlet anymore
His weight is 180

On line 29 and 33 we were able to access and change the fields age and weight just as if they were declared as fields of the Student struct. This is because fields of Human are embedded in the struct Student.

Cool, isn't it? But there's more than this interpolation of fields, an anonymous field can be used with its type as its name!

This means that Student has a field named Human that can be used as regular field with this name.

Anonymous fields of any type

Accessing, and changing an anonymous field by name is quite useful for anonymous fields that are not structs. * -- Who told you that anonymous fields must be* structs?! * -- I didn't!*

In fact, any named type and pointers to named types are completely acceptable.

Let's see some anonymous action:

Output:

Her name is Jane
Her age is 35
Her weight is 100
Her speciality is Biology
Her skills are [anatomy]
She acquired two new ones
Her skills now are [anatomy physics golang]
Her preferred number is 3

The anonymous field mechanism lets us inherit some (or even all) of the implementation of a given type from another type or types.

Anonymous fields conflicts

What happens if Human has a field phone and Student has also a field with the same name?

This kind of conflicts are solved in Go simply by saying that the outer name hides the inner one. i.e. when accessing phone you are working with Student's one.

This provides a way to override a field that is present in the "inherited" anonymous field by the one that we explicitely specify in our type.

If you still need to access the anonymous one, you'll have to use the type's name syntax:

Output:

Bob's work phone is: 333-222
Bob's personal phone is: 777-444-XXXX

Great! So now you ask,

"Now, what does all this have to do with methods?"

Attaboy, you didn't forget the main subject of the chapter. Kudos.

Methods on anonymous fields

The good surprise is that methods behave exactly like anonymous fields. If an anonymous field implements a given method, this method will be available for the type that is using this anonymous field.

If the Human type implements a method SayHi() that prints a greeting, this same method is available for both Student and Employee! You won't need to write it twice for them:

Output:

Hi, I am Mark you can call me on 222-222-YYYY
Hi, I am Sam you can call me on 111-888-XXXX

Philosophy

Think about it: you often need to represent things that share some attributes or characteristics, this is solved with the anonymous field mechanism. And when you need to represent a shared behavior or functionality, you can use a method on an anonymous field.

Overriding a method

What if you want the Employee to tell you where he works as well? Easy, the same rule for overriding fields on conflicts applies for methods, and we happily exploit this fact:

Output:

Hi, I am Mark you can call me on 222-222-YYYY
Hi, I am Sam, I work at Golang Inc. Call me on 111-888-XXXX

And... It worked like a charm!

With these simple concepts, you can now design shorter, nicer and expressive programs. In the next chapter we will learn how to enhance this experience even more with a new notion: Interfaces.