Golang が継承よりも構成を好むのはなぜですか?

Nov 06 2022
Go は通常、オブジェクト指向言語であると宣伝されていますが、舞台裏では別のものにすぎません。通常、オブジェクト指向言語では継承が使用されますが、Go では合成が好まれます。その理由は次のとおりです。 継承の問題: (i) 大規模な階層 (ii) 密結合 継承について説明しましょう:

Go は通常、オブジェクト指向言語であると宣伝されていますが、舞台裏では別のものにすぎません。通常、オブジェクト指向言語では継承が使用されますが、Go では合成が優先されます。その理由は次のとおりです。

継承の問題:

(i) 大規模な階層 (ii) 密結合

継承について議論しましょう:

継承:

「is a」関係に対応します。食べることと寝ることの属性を持つ動物の例を見てみましょう。動物から継承される可能性のあるクラスは、犬、人、魚です。現在の属性は継承されたクラスに沿ってうまくいくかもしれませんが、現在の属性に歩行の属性が追加された場合、これはうまくいくと思いますか?魚には歩く能力がないので、単純な答えは「いいえ」です。継承を使用したい場合、簡単な解決策の 1 つは、型ごとにカテゴリを作成することです。次のようになります。

これに関する問題は、新しい属性を追加するたびに、既に定義されているクラスに追加する必要があることです。これが構成の出番です。

構成:

「has a」関係に相当します。これで、動物が「生きている」ことができるように属性を定義できます。つまり、食べたり寝たりすることができます。「has a」関係を維持することは「is a」関係を維持することよりも簡単であるため、Go ではコンポジションが好まれるのはそのためです。

Goでコンポジションを実装する方法は次のとおりです。

package main

import "fmt"

type alive struct {
}
type walkable struct {
}
type swimable struct {
}
type duck struct {
a alive
w walkable
s swimable
}

func (d duck) eat() {
d.a.eat()
}
func (d duck) sleep() {
d.a.sleep()
}
func (d duck) walk() {
d.w.walk()
}
func (d duck) swim() {
d.s.swim()
}
func (alive) eat() {
fmt.Println("Alive and eating")
}
func (alive) sleep() {
fmt.Println("Alive and sleeping")
}
func (walkable) walk() {
fmt.Println("strolling through")
}
func (swimable) swim() {
fmt.Println("Taking a dip")
}
func main() {
d := duck{}
d.eat()
d.sleep()
d.walk()
d.swim()
}

      
                

© Copyright 2021 - 2022 | hachiwiki.com | All Rights Reserved