ترکیب (Composition)

Embedding در Go — جایگزین ارث‌بری با ترکیب رفتارها.

ارث‌بری نداریم — ترکیب داریم!

Go برخلاف Java/C++ ارث‌بری (Inheritance) ندارد. به جای آن از ترکیب (Composition) و Embedding استفاده می‌کند — ساده‌تر و انعطاف‌پذیرتر!

Embedding چیست؟

قرار دادن یک struct داخل struct دیگر بدون نام فیلد:

type Animal struct {
    Name string
}

type Dog struct {
    Animal          ← بدون نام = Embedding!
    Breed string
}

دسترسی به فیلدهای Embedded

dog := Dog{
    Animal: Animal{Name: "رکس"},
    Breed:  "ژرمن",
}

fmt.Println(dog.Name)        ← رکس (مستقیم!)
fmt.Println(dog.Animal.Name) ← رکس (مسیر کامل)

Embedded متدها هم به ارث می‌رسند!

func (a Animal) Speak() string {
    return a.Name + " صدا می‌کند"
}

type Dog struct {
    Animal
}

dog := Dog{Animal: Animal{Name: "رکس"}}
fmt.Println(dog.Speak())   ← رکس صدا می‌کند

Override — بازنویسی رفتار

اگر نوع بیرونی متد هم‌نام تعریف کند، جایگزین می‌شود:

func (d Dog) Speak() string {
    return d.Name + " واق واق می‌کند!"
}

dog.Speak()   ← رکس واق واق می‌کند!

دسترسی به متد والد (مثل super)

func (d Dog) Speak() string {
    return d.Animal.Speak() + " — واق واق!"
}

Embedding چندگانه

type Walker struct{}
func (w Walker) Walk() string { return "راه می‌رود" }

type Swimmer struct{}
func (s Swimmer) Swim() string { return "شنا می‌کند" }

type Amphibian struct {
    Walker     ← هر دو رفتار!
    Swimmer
}

frog := Amphibian{}
frog.Walk()   ← راه می‌رود
frog.Swim()   ← شنا می‌کند

Embedding اینترفیس هم می‌شود!

type Logger struct {
    // اینترفیس embedded
    Writer io.Writer
}
شعار Go: «ترکیب بهتر از ارث‌بری است» — Embedding کد را بدون سلسله‌مراتب پیچیده بازاستفاده می‌کند!

این مبحث بخشی از دوره آموزش کامل گو است.

ابزارهای مرتبط