مرکزی مواد پر جائیں
ماڈیول 3 · سبق 2 از 2کورس میں 6/14~15 min
ماڈیول اسباق (2/2)

پولیمورفزم اور خلاصہ کلاسز

پولیمورفزم اور تجریدی کلاسز جدید آبجیکٹ پر مبنی پروگرامنگ کے تصورات ہیں جو ہمیں مخصوص نفاذ سے آزاد لچکدار، قابل توسیع کوڈ لکھنے کی اجازت دیتے ہیں۔

پولیمورفزم

اصطلاح پولیمورفزم (کئی شکلیں) سے مراد مختلف طبقوں کی اشیاء کے ساتھ ایسا سلوک کرنے کی صلاحیت ہے جیسے وہ ایک عام قسم سے تعلق رکھتے ہوں۔ جاوا میں، ایک سپر کلاس حوالہ متغیر اس کے کسی بھی ذیلی طبقے کی کسی چیز کا حوالہ محفوظ کر سکتا ہے۔

Java
class Animal {
    public void makeSound() {
        System.out.println("Verso...");
    }
}

class Dog extends Animal {
    public void makeSound() {
        System.out.println("Woof");
    }
}

class Cat extends Animal {
    public void makeSound() {
        System.out.println("Miao");
    }
}

پولیمورفزم کا شکریہ، ہم یہ کر سکتے ہیں:

Java
Animal myAnimal1 = new Dog(); // Polymorphism
Animal myAnimal2 = new Cat(); // Polymorphism

myAnimal1.makeSound(); // Executes Dog's method (Woof)
myAnimal2.makeSound(); // Executes Cat's method (Miao)

یہ فیصلہ رن ٹائم (لیٹ بائنڈنگ یا ڈائنامک ڈسپیچ) کے وقت کیا جاتا ہے، نہ کہ حوالہ متغیر کی قسم کی بنیاد پر۔

خلاصہ کلاسز (abstract)

ایک خلاصہ کلاس ایک کلاس ہے جس کو abstract کلیدی لفظ سے نشان زد کیا گیا ہے جسے براہ راست انسٹیٹیوٹ نہیں کیا جا سکتا (آپ new MyAbstractClass() نہیں کر سکتے)۔ یہ دوسری کلاسوں کے لیے "جزوی ٹیمپلیٹ" کے طور پر کام کرتا ہے۔

خلاصہ کے طریقے

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

Java
abstract class Shape {
    String color;

    // Abstract method (no body)
    public abstract double getArea();
}

class Circle extends Shape {
    double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    // Required to implement getArea
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

متحرک بائنڈنگ / لیٹ بائنڈنگ

جاوا کیسے جانتا ہے کہ رن ٹائم کے وقت کون سا طریقہ چلانا ہے؟ اس عمل کو لیٹ بائنڈنگ (یا ڈائنامک بائنڈنگ) کے نام سے جانا جاتا ہے۔ اوور لوڈنگ کے برعکس (جو مرتب وقت پر حل ہو جاتا ہے)، مرتب کرنے والا نہیں جانتا کہ کون سا مخصوص طریقہ کار انجام دیا جائے گا۔ اس کے بجائے، یہ ایک عام کال کی ہدایات تیار کرتا ہے۔ رن ٹائم کے وقت، جاوا ورچوئل مشین (JVM) میموری میں اصل آبجیکٹ کا معائنہ کرتی ہے اور اس آبجیکٹ کی کلاس میں بیان کردہ طریقہ پر عمل درآمد کی درخواست کرتی ہے۔

خلاصہ کلاسز اور لاپتہ نفاذ

اگر ذیلی طبقے کو تجریدی کلاس سے وراثت ملتی ہے، تو اس کے پاس دو اختیارات ہیں:

  1. تمام تجریدی طریقوں کو نافذ کریں: اس صورت میں، ذیلی کلاس ایک عام (کنکریٹ) کلاس ہوسکتی ہے اور اسے فوری بنایا جاسکتا ہے۔
  2. خود کو خلاصہ کا اعلان کریں: اگر ذیلی کلاس تمام وراثتی تجریدی طریقوں کے لیے نفاذ فراہم نہیں کرتی ہے، تو اسے abstract کلیدی لفظ کے ساتھ بھی اعلان کیا جانا چاہیے۔
Java
abstract class Animal {
    public abstract void makeSound();
}

// This class MUST be abstract because it does not implement makeSound()
abstract class Canine extends Animal {
    // Inherits makeSound() but does not implement it
}

خود ہی آزمائیں۔

ورزش#java.m3.l2.e1
کوششیں: 0لوڈ ہو رہا ہے…

ایک متغیر s قسم کی شکل کا اعلان کریں اور پولیمورفزم کا استعمال کرتے ہوئے اسے ایک نیا سرکل آبجیکٹ تفویض کریں۔

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

بنیادی قسم کو حوالہ کی قسم کے طور پر استعمال کرنے کے لیے `Shape s = new Circle();` لکھیں۔

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

ورزش#java.m3.l2.e2
کوششیں: 0لوڈ ہو رہا ہے…

شکل کلاس کو خلاصہ بنائیں اور تجریدی طریقہ کو ڈبل getArea() شامل کریں۔ پھر اسکوائر کو مکمل کریں تاکہ یہ شکل کو بڑھا دے اور getArea() کو واپس کرنے والی سائیڈ * سائیڈ کو لاگو کرے۔

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

شکل میں `عوامی خلاصہ ڈبل getArea();` کا اعلان کریں۔ اسکوائر میں، `@Override public double getArea() { ریٹرن سائیڈ * سائیڈ شامل کریں؛ }`

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

ورزش#java.m3.l2.e3
کوششیں: 0لوڈ ہو رہا ہے…

مرکزی طریقہ میں شکل [] کی ایک صف کا اعلان کریں جس میں رداس 2.0 کے ساتھ ایک دائرہ آبجیکٹ اور سائیڈ 3.0 کے ساتھ ایک مربع آبجیکٹ ہو۔ پھر، getArea() طریقہ استعمال کر کے ہر شکل کے علاقے کو پرنٹ کرنے کے لیے ایک لوپ (for یا for-each) کا استعمال کریں۔

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

`Shape[] شکلوں = { new Circle(2.0), new Square(3.0) };` کے ساتھ صف کا اعلان کریں اور `s.getArea()` پرنٹنگ کے لئے `(شکل s : شکلیں)` کا استعمال کرتے ہوئے اس کے ذریعے لوپ کریں۔

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