مرکزی مواد پر جائیں
ماڈیول 5 · سبق 3 از 5کورس میں 23/50~12 min
ماڈیول اسباق (3/5)

ساخت (ایمبیڈنگ)

جاؤ کوئی وراثت نہیں ہے۔ دوبارہ استعمال کرنے کا محاورہ جواب ہے۔ کمپوزیشن، اور خاص طور پر ایمبیڈنگ: ایک قسم سمیت فیلڈ کا نام دیئے بغیر دوسرے کے اندر۔ کے میدان اور طریقے سرایت شدہ قسم کو فروغ دیا گیا، براہ راست قابل رسائی بننا گویا وہ بیرونی قسم سے تعلق رکھتے تھے۔

سٹرک ایمبیڈنگ

Go
type Animal struct {
    Name string
}

func (a Animal) Greet() string {
    return "ciao da " + a.Name
}

type Dog struct {
    Animal        // embedding — NO field name
    Breed string
}

c := Dog{
    Animal: Animal{Name: "Rex"},
    Breed:  "Pastore",
}

fmt.Println(c.Name)         // "Rex" — promoted from Animal
fmt.Println(c.Greet())      // "ciao da Rex" — promoted method
fmt.Println(c.Breed)        // own field

سرایت شدہ فیلڈ اب بھی قسم کے نام سے قابل رسائی ہے: c.Animal.Name کام کرتا ہے اور c.Name سے مماثل ہے۔ اس کی ضرورت ہے جب تصادم ہیں.

اوور رائڈ (جزوی): طریقہ "شیڈونگ"

اگر بیرونی قسم اسی نام کے ساتھ ایک طریقہ کی وضاحت کرتی ہے جسے فروغ دیا گیا ہے۔ ایک، اس کا طریقہ "جیت"۔ اندر سے آپ ہمیشہ ایمبیڈڈ تک پہنچ سکتے ہیں۔ ایک قسم کے نام کے ذریعے:

Go
func (c Dog) Greet() string {
    return "BAU! " + c.Animal.Greet()
}

یہ پولیمورفک وراثت نہیں ہے: یہ صرف لغوی نام کی قرارداد ہے۔ پولیمورفزم کے لیے آپ انٹرفیس (ماڈیول 6) استعمال کرتے ہیں۔

ایک سے زیادہ سرایت کرنا

آپ متعدد اقسام کو سرایت کر سکتے ہیں:

Go
type Logger struct{ /*...*/ }
func (l Logger) Log(msg string) { /*...*/ }

type Timer struct{ /*...*/ }
func (t Timer) Now() time.Time { /*...*/ }

type Service struct {
    Logger
    Timer
    Name string
}

s := Service{Name: "api"}
s.Log("start")   // promoted from Logger
s.Now()          // promoted from Timer

اگر دو ایمبیڈڈ اقسام میں ایک ہی نام کا طریقہ ہے تو براہ راست رسائی مبہم ہو جاتا ہے اور مرتب کرنے والے کو واضح شکل کی ضرورت ہوتی ہے۔ (s.Logger.Foo() یا s.Timer.Foo())۔

انٹرفیس سرایت کرنا

انٹرفیس کو "ایمبیڈڈ" بھی کیا جا سکتا ہے (ماڈیول 6 دیکھیں):

Go
type ReadWriter interface {
    io.Reader
    io.Writer
}

یہ Reader اور Writer کے طریقوں کے اتحاد کے برابر ہے۔

واضح کمپوزیشن کب استعمال کریں (ایمبیڈنگ نہیں)

اگر آپ ایک نامزد فیلڈ چاہتے ہیں اور کوئی آٹو پروموشن نہیں ہے تو سادہ استعمال کریں۔ ترکیب:

Go
type Dog struct {
    Anim  Animal    // NORMAL field, no promotion
    Breed string
}
c.Anim.Name   // you need the field name

سرایت کرنا ایک آسان ڈیلی گیشن ٹول ہے، ڈیزائن کا انتخاب نہیں۔ واضح مرکب سے سختی سے بہتر: جب آپ واقعی چاہیں استعمال کریں۔ اندرونی قسم کے API کو فروغ دینے کے لیے۔

اسے آزمائیں

ورزش#go.m5.l3.e1
کوششیں: 0لوڈ ہو رہا ہے…

کتے کی وضاحت کریں جو جانوروں کو سرایت کرتا ہے (ایمبیڈنگ، فیلڈ کا کوئی نام نہیں) اور اس کے پاس بریڈ سٹرنگ فیلڈ ہے۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

ایمبیڈنگ: TYPE کو فیلڈ کا نام دیئے بغیر لکھیں۔

3 کوششوں کے بعد حل دستیاب ہے۔

ورزش#go.m5.l3.e2
کوششیں: 0لوڈ ہو رہا ہے…

Animal میں Greet() سٹرنگ کا طریقہ شامل کریں اور اسے براہ راست ڈاگ متغیر (طریقہ فروغ) پر کال کریں۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

اینیمل پر بیان کردہ طریقہ کو سرایت کرنے کی بدولت کتے میں فروغ دیا جاتا ہے۔

3 کوششوں کے بعد حل دستیاب ہے۔

Quiz#go.m5.l3.e3
تیار

کیا گو کلاسیکی وراثت کی حمایت کرتا ہے؟

Go
type B struct { /* extends A? */ }
جواب کے اختیارات

Recap

  • کوئی وراثت نہیں: آپ ایمبیڈنگ کے ساتھ کمپوز کرتے ہیں۔
  • ایمبیڈنگ = ساخت میں فیلڈ کے نام کے بغیر ٹائپ لکھنا۔
  • سرایت شدہ قسم کے فیلڈز اور طریقوں کو فروغ دیا جاتا ہے۔
  • واضح رسائی ہمیشہ دستیاب ہے: outer.Inner.Field۔
  • "لغوی" اوور رائڈ: بیرونی قسم کا طریقہ ترقی یافتہ کو سایہ کرتا ہے۔
  • ایمبیڈنگ ≠ is-a: پولیمورفزم کے لیے انٹرفیس استعمال کریں۔