** Addition ** Not object-oriented in Go language, this is Go-like object-oriented! There seems to be a bad word I have received various suggestions in the comment section, so I would appreciate it if you could check them.
I joined DIP Corporation halfway and made API in Go language. Until now, I've been talking about loose object-oriented languages such as PHP and Ruby every day.
Even so, I had the opportunity to make use of my previous work experience. This time, I would like to talk about "I made the Go language source feel good by making use of my previous work experience."
As anyone who works with the Go language knows, there is no object orientation in the Go language. There are no classes, no inheritance, no constructors. The object thinking (not typographical errors) that I have cultivated so far is like garbage.
If you implement it with Go, you should implement it like Go obediently, but even so, the idea that "if this is object-oriented, it should be implemented like this" is overwhelming. When I searched the internet for a long time, I found some "how to do object-oriented things in Go language". I made a nice implementation with reference to them, so I will summarize it with a sample.
There are many things that are object-oriented, but this time we will aim for this area.
package main
import (
"fmt"
)
const line = "--------------------"
func main() {
wiz := newWizard("Magical girl", 10, 10, 5)
war := newWarrior("+‡†Berserker†‡+", 10, 15, 30)
fmt.Println(wiz.hello())
fmt.Println(war.hello())
fmt.Println(line)
fmt.Println(wiz.attack())
fmt.Println(war.attack())
fmt.Println(line)
fmt.Println(wiz.magic())
fmt.Println(war.attack())
}
type human struct {
name string
hp int
ap int
}
func (h *human) init(name string, hp, ap int) {
h.name = name
h.hp = hp
h.ap = ap
}
func (h *human) hello() string {
return fmt.Sprintf("Hello, I%s.", h.name)
}
func (h *human) attack() string {
return fmt.Sprintf("%s attack!%d damage!", h.name, h.ap)
}
type wizard struct {
human
mp int
}
func newWizard(name string, hp, ap, mp int) *wizard {
w := new(wizard)
w.init(name, hp, ap)
w.mp = mp
return w
}
func (w *wizard) magic() string {
if w.mp <= 0 {
return fmt.Sprintf("%s has no power", w.name)
}
w.mp -= 1
return fmt.Sprintf("%s used magic! 30 damage!", w.name)
}
type warrior struct {
human
}
func newWarrior(name string, hp, ap, mp int) *warrior {
w := new(warrior)
w.init(name, hp, ap)
return w
}
func (w *warrior) attack() string {
return fmt.Sprintf("%s attack!%d damage!", w.name, w.ap*2)
}
Execution result
Hello, I'm a magical girl.
Hello, I+‡†Berserker†‡+is.
--------------------
Magical girl attack! 10 damage!
+‡†Berserker†‡+Attack! 30 damage!
--------------------
The magical girl used magic! 30 damage!
+‡†Berserker†‡+Attack! 30 damage!
A common RPG professional guy
type human struct {
name string
hp int
ap int
}
Define properties to be used in common
func (h *human) init(name string, hp, ap int) {
h.name = name
h.hp = hp
h.ap = ap
}
There is no structure in Go, so you can define any method that does the work of the constructor. I'm naming it ʻinit` here, but anything is fine
func (h *human) hello() string {
return fmt.Sprintf("Hello, I%s.", h.name)
}
func (h *human) attack() string {
return fmt.Sprintf("%s attack!%d damage!", h.name, h.ap)
}
type wizard struct {
human
mp int
}
type warrior struct {
human
}
By specifying the parent class (structure), the properties and methods defined in the parent class (structure) can be included (not inherited). If you want to increase the properties by the small class (structure), you can continue to describe it (either before or after).
func newWizard(name string, hp, ap, mp int) *wizard {
w := new(wizard)
w.init(name, hp, ap)
w.mp = mp
return w
}
func newWarrior(name string, hp, ap, mp int) *warrior {
w := new(warrior)
w.init(name, hp, ap)
return w
}
Create an instance of the parent class (structure) and call the constructor. If you want to make initial settings unique to the child class (structure), describe them continuously.
func (w *wizard) magic() string {
if w.mp <= 0 {
return fmt.Sprintf("%s has no power", w.name)
}
w.mp -= 1
return fmt.Sprintf("%s used magic! 30 damage!", w.name)
}
It is also possible to generate methods dedicated to small classes (structures)
func (w *warrior) smash() string {
return fmt.Sprintf("%Strong attack of s!%d damage!", w.name, w.ap*2)
}
You can make your own behavior by defining a method with the same name.
func main() {
wiz := newWizard("Magical girl", 10, 10, 5)
war := newWarrior("+‡†Berserker†‡+", 10, 15, 30)
fmt.Println(wiz.hello())
fmt.Println(war.hello())
fmt.Println(line)
fmt.Println(wiz.attack())
fmt.Println(war.attack())
fmt.Println(line)
fmt.Println(wiz.magic())
fmt.Println(war.smash())
}
Create an instance by calling the factory of the child class (structure) without worrying about the parent class (structure). Enjoy by calling common methods or unique methods.
You can even go with Go language! And a good feeling. The implementation has become simple. I think it is ant to use it to the extent that the processing is not complicated.
I'm sure I implemented it by picking up information from many articles and sites, but I forgot the URL when I initialized my PC. We apologize and thank you, and note that this is not a completely original article. Everyone backs up frequently.
Recommended Posts