GoLang オブジェクト指向

この記事の一部は機械翻訳を使ってるよ

Golang シリーズ

Hello GoLang: https://blog.yexca.net/ja/archives/154
GoLang (var and const) 変数と定数: https://blog.yexca.net/ja/archives/155
GoLang (func) 関数: https://blog.yexca.net/ja/archives/156
GoLang (slice and map) スライス: https://blog.yexca.net/ja/archives/160
GoLang (OOP) オブジェクト指向: この記事
GoLang (reflect) リフレクション: https://blog.yexca.net/ja/archives/204
GoLang (struct tag) 構造タグ: https://blog.yexca.net/ja/archives/205
GoLang (goroutine) ゴルーチン: https://blog.yexca.net/ja/archives/206
GoLang (channel) チャンネル: https://blog.yexca.net/ja/archives/207


造を使用してクラスとオブジェクトの概念を構築する

オブジェクト指向を理解する: オブジェクト指向の基礎(簡体字中国語だけど)

struct

まずは、C に似た type キーワードを使用したカスタム型です。

package main

import "fmt"

type myType int

func main() {
    var a myType
    fmt.Println("a =", a)
    fmt.Printf("type of a is %T", a)
}

/*
 * 出力
 * a = 0
 * type of a is main.myTye
 */

stuct を使用して型を定義する

package main

import "fmt"

type Person struct {
    name string
    age  int
}

fun     main() {
    var zhang Person
    zhang.name = "zhangSan"
    zhang.age = 20

    fmt.Print(zhang)
}

関数転送は関連しており、ポインタは使用されず、値の転送です

package main

import "fmt"

type Person struct {
    name string
    age  int
}

// 値の転送、元のデータは変更されません
func changeName(person Person) {
    person.name = "liSi"
}

// 参照を渡すと元のデータが変更されます
func changeAge(person *Person) {
    person.age = 18
}

func main() {
    var zhang Person
    zhang.name = "zhangSan"
    zhang.age = 20

    fmt.Println(zhang)

    changeName(zhang)
    fmt.Println(zhang)

    changeAge(&zhang)
    fmt.Println(zhang)
}

カプセル化

package main

import "fmt"

// クラス
type Person struct {
    // プロパティ
    name string
    age  int
}

// クラスメソッド
func (this *Person) SetName(name string) {
    this.name = name
}
func (this *Person) SetAge(age int) {
    this.age = age
}
func (this *Person) GetName() string {
    return this.name
}
func (this *Person) GetAge() int {
    return this.age
}

func main() {
    person := Person{name: "zhangSan", age: 18}
    fmt.Println(person)
}

クラス名とメソッド名の最初の文字が大文字になっていることに注意してください。これは、クラスとメソッドが他のパッケージからアクセスできることを意味します (java public)。最初の文字が小文字の場合は、このパッケージからのみアクセスできます (java private) プロパティについても同様です。

継承

次のコードは同じファイル、親クラスにあります

// 親クラス
type Person struct {
    name string
    age  int
}

// 親クラスのメソッド
func (this *Person) Eat() {
    fmt.Println("Person Eat...")
}
func (this *Person) Walk() {
    fmt.Println("Person Walk...")
}

サブクラス

// サブクラス
type SuperMan struct {
    Person     // 親クラスから継承
    level  int // サブクラス属性
}

// サブクラスは親クラスのメソッドをオーバーライドします
func (this *SuperMan) Walk() {
    fmt.Println("SuperMan Walk")
}
// サブクラス固有のメソッド
func (this *SuperMan) Fly() {}
    

main 関数

func main() {
    // サブクラスの属性を定義する、方法 1
    superMan1 := SuperMan{Person{"zhangSan", 18}, 4}
    // サブクラスの属性を定義する、方法 2
    var superMan2 SuperMan
    superMan2.name = "liSi" // 同じパッケージ内にあるため、親クラスの属性にアクセスできます
    superMan2.age = 20
    superMan2.level = 5

    // サブクラスは親クラスのメソッドを呼び出す
    superMan1.Eat()
    // サブクラスのオーバーライドメソッド
    superMan1.Walk()
    // サブクラスメソッド
    superMan2.Fly()
}

多態性

次のコードは同じファイルにあり、インターフェースを定義しています

// インターフェース、基本的にはポインタ
type Animal interface {
    Sleep()
    GetName() string
    GetType() string
}

実装クラス 1

// 実装クラス 1
type Cat struct {
    name string
    kind string
}

// インターフェースのすべてのメソッドを実装する
func (this *Cat) Sleep() {
    fmt.Println("Cat Sleep()")
}
func (this *Cat) GetName() string {
    return this.name
}
func (this *Cat) GetType() string {
    return this.kind
}

実装クラス 2

// 実装クラス 2
type Dog struct {
    name string
    kind string
}

// インターフェースのすべてのメソッドを実装する
func (this *Dog) Sleep() {
    fmt.Println("Cat Sleep()")
}
func (this *Dog) GetName() string {
    return this.name
}
func (this *Dog) GetType() string {
    return this.kind
}

func ShowAnimal(animal Animal) {
    fmt.Println(animal)
}

main

func ShowAnimal(animal Animal) {
    fmt.Println(animal)
}

func main() {
    var animal Animal
    animal = &Cat{"cat1", "cat"}
    animal.Sleep()
    animal = &Dog{"dog1", "dog"}
    animal.Sleep()

    cat := Cat{"cat2", "cat"}
    dog := Dog{"dog2", "dog"}

    ShowAnimal(&cat)
    ShowAnimal(&dog)

}

ユニバーサル型とアサーション

package main

import "fmt"

// ユニバーサルデータ型を表すために空のインターフェースを使用する
func f(arg interface{}) {
    // 型アサーションメカニズム (つまり型変換)
    value, flag := arg.(string)
    if !flag {
        fmt.Println("arg is not string type")
    } else {
        fmt.Println("arg is string type, arg =", value)
    }
}

func main() {
    // カスタムを含む任意のデータ型を渡すことができます
    f("abc")
    f(123)
    f(3.14)
}

/*
 * 出力
 * arg is string type, arg = abc
 * arg is not string type
 * arg is not string type
 */
This post is licensed under CC BY-NC-SA 4.0 by the author.
最終更新 2025-01-28 20:17 +0900

Hugo で構築されています。 | テーマ StackJimmy によって設計されています。