Do something object-oriented in GO language

** 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."

Go language is not object oriented

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.

Thing you want to do

There are many things that are object-oriented, but this time we will aim for this area.

Implementation example

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

Description of implementation contents

Parent class (structure)

type human struct {
	name string
	hp int
	ap int
}

Define properties to be used in common

Parent class (structure) constructor

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

Method hanging from parent class (structure)

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)
}

Child class (structure)

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).

Small class (structure) factory

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.

Small class (struct) method (new)

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)

Small class (structure) method (overwrite)

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.

Example of use

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.

Try an object-oriented implementation

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.

Referenced page

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

Do something object-oriented in GO language
Try implementing Yubaba in Go language
Use optinal type-like in Go language
Post to slack in Go language
Do something like Redis transactions in Python
Java programmer touched Go language (Implement Java inheritance in Go language)
I wrote the hexagonal architecture in go language
Create a web server in Go language (net/http) (2)
What I do when imitating embedded go in python
Write Pulumi in Go
Go language learning record
Go language environment construction
Go language cheat sheet
Create a web server in Go language (net / http) (1)
I want to do something in Python when I finish
Go language to see and remember Part 7 C language in GO language
[Python version] Why can't you do object-oriented development in Java?
[Go language] How to get terminal input in real time
I want to do something like sort uniq in Python
Do something like a Python interpreter in Visual Studio Code
Machine language embedding in C language
Implement recursive closures in Go
Programming language in "Hello World"
go language learning miscellaneous notes 1
[Golang] About Go language channel
Do something fuzzing with acceptableRegex.py
Created a package to support AWS Lambda development in Go language
Created gomi, a trash can tool for rm in Go language
PySide --do something in the background while displaying a modeless dialog
I wanted to do something like an Elixir pipe in Python
Read the config file in Go language! Introducing a simple sample