JavaRush /جاوا بلاگ /Random-UR /پولیمورفزم اور اس کے دوست
Viacheslav
سطح

پولیمورفزم اور اس کے دوست

گروپ میں شائع ہوا۔
پولیمورفزم آبجیکٹ پر مبنی پروگرامنگ کے بنیادی اصولوں میں سے ایک ہے۔ یہ آپ کو جاوا کی مضبوط ٹائپنگ کی طاقت کو استعمال کرنے اور قابل استعمال اور برقرار رکھنے کے قابل کوڈ لکھنے کی اجازت دیتا ہے۔ اس کے بارے میں بہت کچھ کہا گیا ہے، لیکن مجھے امید ہے کہ ہر کوئی اس جائزے سے کچھ نیا لے سکتا ہے۔
پولیمورفزم اور اس کے دوست - 1

تعارف

میرے خیال میں ہم سب جانتے ہیں کہ جاوا پروگرامنگ لینگویج اوریکل سے تعلق رکھتی ہے۔ لہذا، ہمارا راستہ اس سائٹ سے شروع ہوتا ہے: www.oracle.com ۔ مرکزی صفحہ پر ایک "مینو" ہے۔ اس میں، "دستاویزات" سیکشن میں ایک "جاوا" سب سیکشن ہے۔ ہر وہ چیز جو زبان کے بنیادی افعال سے متعلق ہے "جاوا SE دستاویزات" سے تعلق رکھتی ہے، لہذا ہم اس حصے کو منتخب کرتے ہیں۔ دستاویزات کا سیکشن تازہ ترین ورژن کے لیے کھل جائے گا، لیکن ابھی کے لیے "ایک مختلف ریلیز کی تلاش ہے؟" آئیے آپشن کا انتخاب کریں: JDK8۔ صفحہ پر ہم بہت سے مختلف اختیارات دیکھیں گے۔ لیکن ہم زبان سیکھنے میں دلچسپی رکھتے ہیں: " Java Tutorials Learning Paths "۔ اس صفحہ پر ہمیں ایک اور سیکشن ملے گا: " جاوا زبان سیکھنا "۔ یہ مقدس ترین ہولیز ہے، اوریکل سے جاوا کی بنیادی باتوں پر ایک سبق ہے۔ جاوا ایک آبجیکٹ اورینٹڈ پروگرامنگ لینگویج (OOP) ہے، لہٰذا اوریکل ویب سائٹ پر بھی زبان سیکھنا " آبجیکٹ اورینٹڈ پروگرامنگ تصورات " کے بنیادی تصورات پر بحث کے ساتھ شروع ہوتا ہے۔ نام سے ہی یہ واضح ہے کہ جاوا اشیاء کے ساتھ کام کرنے پر مرکوز ہے۔ " آبجیکٹ کیا ہے؟ " سب سیکشن سے ، یہ واضح ہے کہ جاوا میں آبجیکٹ ریاست اور رویے پر مشتمل ہوتے ہیں۔ تصور کریں کہ ہمارا ایک بینک اکاؤنٹ ہے۔ اکاؤنٹ میں رقم کی رقم ایک ریاست ہے، اور اس ریاست کے ساتھ کام کرنے کے طریقے رویے ہیں۔ اشیاء کو کسی نہ کسی طرح بیان کرنے کی ضرورت ہے (بتائیں کہ ان کی کیا حالت اور طرز عمل ہو سکتا ہے) اور یہ تفصیل ہے class ۔ جب ہم کسی کلاس کا آبجیکٹ بناتے ہیں تو ہم اس کلاس کو بتاتے ہیں اور اسے " آبجیکٹ ٹائپ " کہا جاتا ہے۔ اس لیے یہ کہا جاتا ہے کہ جاوا ایک مضبوطی سے ٹائپ کی جانے والی زبان ہے، جیسا کہ جاوا زبان کی وضاحت میں سیکشن " باب 4. اقسام، قدریں، اور متغیرات " میں بیان کیا گیا ہے۔ جاوا زبان OOP تصورات کی پیروی کرتی ہے اور توسیعی کلیدی لفظ کا استعمال کرتے ہوئے وراثت کی حمایت کرتی ہے۔ توسیع کیوں؟ کیونکہ وراثت کے ساتھ، ایک بچہ طبقہ والدین کے طبقے کے طرز عمل اور حالت کا وارث ہوتا ہے اور ان کی تکمیل کر سکتا ہے، یعنی بیس کلاس کی فعالیت کو بڑھانا۔ ایک انٹرفیس کو کلاس ڈسکرپشن میں امپلیپلس کی ورڈ کا استعمال کرتے ہوئے بھی بیان کیا جا سکتا ہے۔ جب ایک کلاس انٹرفیس کو لاگو کرتی ہے، تو اس کا مطلب ہے کہ کلاس کچھ معاہدے کے مطابق ہوتی ہے - پروگرامر کی طرف سے باقی ماحول کے لیے ایک اعلان کہ کلاس کا ایک خاص رویہ ہے۔ مثال کے طور پر، کھلاڑی کے پاس مختلف بٹن ہوتے ہیں۔ یہ بٹن کھلاڑی کے رویے کو کنٹرول کرنے کے لیے ایک انٹرفیس ہیں، اور یہ رویہ کھلاڑی کی اندرونی حالت کو بدل دے گا (مثال کے طور پر حجم)۔ اس صورت میں، ریاست اور رویے ایک وضاحت کے طور پر ایک کلاس دے گا. اگر کوئی کلاس انٹرفیس کو لاگو کرتی ہے، تو اس کلاس کا استعمال کرتے ہوئے تخلیق کردہ کسی شے کو نہ صرف کلاس کے ذریعے، بلکہ انٹرفیس کے ذریعے بھی بیان کیا جا سکتا ہے۔ آئیے ایک مثال دیکھتے ہیں:
public class MusicPlayer {

    public static interface Device {
        public void turnOn();
        public void turnOff();
    }

    public static class Mp3Player implements Device {
        public void turnOn() {
            System.out.println("On. Ready for mp3.");
        }
        public void turnOff() {
            System.out.println("Off");
        }
    }

    public static class Mp4Player extends Mp3Player {
        @Override
        public void turnOn() {
            System.out.println("On. Ready for mp3/mp4.");
        }
    }

    public static void main(String []args) throws Exception{
        // Какое-то устройство (Тип = Device)
        Device mp3Player = new Mp3Player();
        mp3Player.turnOn();
        // У нас есть mp4 проигрыватель, но нам от него нужно только mp3
        // Пользуемся им How mp3 проигрывателем (Тип = Mp3Player)
        Mp3Player mp4Player = new Mp4Player();
        mp4Player.turnOn();
    }
}
قسم ایک بہت اہم تفصیل ہے۔ یہ بتاتا ہے کہ ہم کس طرح آبجیکٹ کے ساتھ کام کرنے جا رہے ہیں، یعنی ہم اعتراض سے کس طرز عمل کی توقع کرتے ہیں۔ رویے طریقے ہیں۔ لہذا، آئیے طریقوں کو سمجھیں۔ اوریکل ویب سائٹ پر، اوریکل ٹیوٹوریل میں طریقوں کا اپنا سیکشن ہے: " طریقوں کی تعریف "۔ مضمون سے سب سے پہلی چیز ہٹانا ہے: طریقہ کا دستخط طریقہ کا نام اور پیرامیٹرز کی اقسام ہیں :
پولیمورفزم اور اس کے دوست - 2
مثال کے طور پر، جب کسی طریقہ کو عوامی باطل طریقہ (Object o) کا اعلان کرتے ہیں، تو دستخط طریقہ کا نام اور پیرامیٹر آبجیکٹ کی قسم ہوگا۔ واپسی کی قسم دستخط میں شامل نہیں ہے۔ یہ ضروری ہے کہ! اگلا، آئیے اپنا سورس کوڈ مرتب کریں۔ جیسا کہ ہم جانتے ہیں، اس کے لیے کوڈ کو کلاس کے نام اور ایکسٹینشن جاوا کے ساتھ فائل میں محفوظ کرنا ضروری ہے۔ جاوا کوڈ کو " javac " کمپائلر کا استعمال کرتے ہوئے کچھ انٹرمیڈیٹ فارمیٹ میں مرتب کیا گیا ہے جسے جاوا ورچوئل مشین (JVM) کے ذریعے عمل میں لایا جا سکتا ہے۔ اس انٹرمیڈیٹ فارمیٹ کو بائٹ کوڈ کہا جاتا ہے اور یہ .class ایکسٹینشن والی فائلوں میں موجود ہے۔ آئیے کمپائل کرنے کے لیے کمانڈ چلائیں: javac MusicPlayer.java جاوا کوڈ کے مرتب ہونے کے بعد، ہم اس پر عمل کر سکتے ہیں۔ شروع کرنے کے لیے " java " یوٹیلیٹی کا استعمال کرتے ہوئے، جاوا ورچوئل مشین کا عمل کلاس فائل میں پاس کیے گئے بائیک کوڈ کو انجام دینے کے لیے شروع کیا جائے گا۔ آئیے ایپلیکیشن لانچ کرنے کے لیے کمانڈ چلائیں: java MusicPlayer. ہم اسکرین پر پرنٹ ایل این میتھڈ کے ان پٹ پیرامیٹر میں بیان کردہ ٹیکسٹ دیکھیں گے۔ دلچسپ بات یہ ہے کہ .class ایکسٹینشن والی فائل میں بائیک کوڈ رکھنے سے، ہم اسے " javap " یوٹیلیٹی کے ذریعے دیکھ سکتے ہیں۔ آئیے کمانڈ چلائیں <ocde>javap -c MusicPlayer:
پولیمورفزم اور اس کے دوست - 3
بائیک کوڈ سے ہم دیکھ سکتے ہیں کہ کسی شے کے ذریعے کسی میتھڈ کو کال کرنا جس کی قسم کلاس کی وضاحت کی گئی تھی، کا استعمال کرتے ہوئے کیا جاتا ہے invokevirtual، اور کمپائلر نے حساب لگایا ہے کہ کون سا طریقہ دستخط استعمال کرنا چاہیے۔ کیوں invokevirtual؟ کیونکہ ایک ورچوئل طریقہ کی کال ہے (دعوت کا ترجمہ کالنگ کے طور پر کیا جاتا ہے)۔ ورچوئل طریقہ کیا ہے؟ یہ ایک ایسا طریقہ ہے جس کے جسم کو پروگرام کے عمل کے دوران اوور رائڈ کیا جا سکتا ہے۔ بس تصور کریں کہ آپ کے پاس ایک مخصوص کلید (طریقہ کے دستخط) اور طریقہ کے باڈی (کوڈ) کے درمیان خط و کتابت کی فہرست ہے۔ اور طریقہ کار کی کلید اور باڈی کے درمیان یہ خط و کتابت پروگرام کے عمل کے دوران تبدیل ہو سکتی ہے۔ اس لیے طریقہ مجازی ہے۔ پہلے سے طے شدہ طور پر، جاوا میں، وہ طریقے جو جامد نہیں، حتمی نہیں، اور نجی نہیں ہیں ورچوئل ہیں۔ اس کی بدولت جاوا پولیمورفزم کے آبجیکٹ پر مبنی پروگرامنگ اصول کی حمایت کرتا ہے۔ جیسا کہ آپ پہلے ہی سمجھ چکے ہوں گے، ہمارا آج کا جائزہ یہی ہے۔

پولیمورفزم

اوریکل کی ویب سائٹ پر ان کے آفیشل ٹیوٹوریل میں ایک الگ سیکشن ہے: " پولیمورفیزم "۔ آئیے جاوا آن لائن کمپائلر کا استعمال کرتے ہوئے دیکھیں کہ جاوا میں پولیمورفزم کیسے کام کرتا ہے۔ مثال کے طور پر، ہمارے پاس کچھ خلاصہ کلاس نمبر ہے جو جاوا میں ایک نمبر کی نمائندگی کرتا ہے۔ یہ کیا اجازت دیتا ہے؟ اس کے پاس کچھ بنیادی تکنیکیں ہیں جو تمام وارثوں کے پاس ہوں گی۔ جو کوئی بھی نمبر سے وراثت میں آتا ہے وہ لفظی طور پر کہتا ہے - "میں ایک نمبر ہوں، آپ میرے ساتھ نمبر کے طور پر کام کر سکتے ہیں۔" مثال کے طور پر، کسی بھی جانشین کے لیے آپ intValue() طریقہ استعمال کر سکتے ہیں تاکہ اس کی عددی قدر حاصل کی جا سکے۔ اگر آپ نمبر کے لیے java api کو دیکھیں تو آپ دیکھ سکتے ہیں کہ طریقہ خلاصہ ہے، یعنی نمبر کے ہر جانشین کو یہ طریقہ خود نافذ کرنا چاہیے۔ لیکن یہ ہمیں کیا دیتا ہے؟ آئیے ایک مثال دیکھتے ہیں:
public class HelloWorld {

    public static int summ(Number first, Number second) {
        return first.intValue() + second.intValue();
    }

    public static void main(String []args){
        System.out.println(summ(1, 2));
        System.out.println(summ(1L, 4L));
        System.out.println(summ(1L, 5));
        System.out.println(summ(1.0, 3));
    }
}
جیسا کہ مثال سے دیکھا جا سکتا ہے، پولیمورفزم کی بدولت، ہم ایک ایسا طریقہ لکھ سکتے ہیں جو کسی بھی قسم کے دلائل کو بطور ان پٹ قبول کرے گا، جو کہ نمبر کی اولاد ہو گی (ہم نمبر حاصل نہیں کر سکتے، کیونکہ یہ ایک تجریدی کلاس ہے)۔ جیسا کہ کھلاڑی کی مثال کا معاملہ تھا، اس معاملے میں ہم کہہ رہے ہیں کہ ہم کسی چیز کے ساتھ کام کرنا چاہتے ہیں، جیسے نمبر۔ ہم جانتے ہیں کہ جو بھی نمبر ہے اسے اس کی عددی قدر فراہم کرنے کے قابل ہونا چاہیے۔ اور ہمارے لیے یہی کافی ہے۔ ہم کسی مخصوص آبجیکٹ کے نفاذ کی تفصیلات میں نہیں جانا چاہتے اور اس چیز کے ساتھ ان طریقوں کے ذریعے کام کرنا چاہتے ہیں جو نمبر کی تمام اولادوں کے لیے عام ہیں۔ ہمارے لیے دستیاب طریقوں کی فہرست مرتب کرنے کے وقت قسم کے لحاظ سے طے کی جائے گی (جیسا کہ ہم نے پہلے بائی کوڈ میں دیکھا تھا)۔ اس صورت میں، ہماری قسم نمبر ہوگی۔ جیسا کہ آپ مثال سے دیکھ سکتے ہیں، ہم مختلف اقسام کے مختلف نمبرز کو پاس کر رہے ہیں، یعنی سمم طریقہ ان پٹ کے طور پر انٹیجر، لانگ اور ڈبل وصول کرے گا۔ لیکن ان سب میں جو چیز مشترک ہے وہ یہ ہے کہ وہ خلاصہ نمبر کی اولاد ہیں، اور اس لیے ان کے رویے کو intValue طریقہ میں اوور رائیڈ کرتے ہیں، کیونکہ ہر مخصوص قسم جانتی ہے کہ اس قسم کو انٹیجر میں کیسے کاسٹ کرنا ہے۔ اس طرح کی پولیمورفزم کو انگریزی میں اوور رائیڈنگ نام نہاد اوور رائیڈنگ کے ذریعے لاگو کیا جاتا ہے۔
پولیمورفزم اور اس کے دوست - 4
اوور رائیڈنگ یا ڈائنامک پولیمورفزم۔ تو، آئیے HelloWorld.java فائل کو درج ذیل مواد کے ساتھ محفوظ کرکے شروع کریں۔
public class HelloWorld {
    public static class Parent {
        public void method() {
            System.out.println("Parent");
        }
    }
    public static class Child extends Parent {
        public void method() {
            System.out.println("Child");
        }
    }

    public static void main(String[] args) {
        Parent parent = new Parent();
        Parent child = new Child();
        parent.method();
        child.method();
    }
}
آئیے کرتے ہیں javac HelloWorld.javaاور javap -c HelloWorld:
پولیمورفزم اور اس کے دوست - 5
جیسا کہ آپ دیکھ سکتے ہیں، میتھڈ کال والی لائنوں کے بائیک کوڈ میں، کال کرنے کے طریقہ کار کا وہی حوالہ اشارہ کیا گیا ہے invokevirtual (#6)۔ چلو کرتے ہیں java HelloWorld. جیسا کہ ہم دیکھ سکتے ہیں، والدین اور بچے کے متغیرات کو والدین کی قسم کے ساتھ قرار دیا جاتا ہے، لیکن عمل درآمد کو خود اس کے مطابق کہا جاتا ہے کہ متغیر کو کس آبجیکٹ کو تفویض کیا گیا تھا (یعنی کس قسم کی آبجیکٹ)۔ پروگرام کے عمل کے دوران (وہ رن ٹائم میں بھی کہتے ہیں)، JVM، آبجیکٹ پر منحصر ہے، جب ایک ہی دستخط کا استعمال کرتے ہوئے طریقوں کو کال کرتا ہے، مختلف طریقوں پر عمل درآمد کرتا ہے۔ یعنی، متعلقہ دستخط کی کلید کا استعمال کرتے ہوئے، ہمیں پہلے ایک طریقہ کا باڈی موصول ہوا، اور پھر دوسرا موصول ہوا۔ اس بات پر منحصر ہے کہ متغیر میں کون سی چیز ہے۔ پروگرام پر عمل درآمد کے وقت یہ تعین کس طریقہ کو کہا جائے گا اسے لیٹ بائنڈنگ یا ڈائنامک بائنڈنگ بھی کہا جاتا ہے۔ یعنی دستخط اور طریقہ کار کے درمیان مماثلت متحرک طور پر انجام دی جاتی ہے، اس چیز پر منحصر ہے جس پر طریقہ کہا جاتا ہے۔ قدرتی طور پر، آپ کلاس کے جامد ممبران (کلاس ممبر) کے ساتھ ساتھ کلاس ممبران کو بھی اوور رائیڈ نہیں کر سکتے ہیں جن تک رسائی کی قسم نجی یا فائنل ہے۔ @Override تشریحات بھی ڈویلپرز کی مدد کے لیے آتی ہیں۔ اس سے مرتب کرنے والے کو یہ سمجھنے میں مدد ملتی ہے کہ اس مقام پر ہم ایک اجداد کے طریقہ کار کے رویے کو اوور رائیڈ کرنے جا رہے ہیں۔ اگر ہم نے طریقہ کار کے دستخط میں غلطی کی ہے، تو مرتب کرنے والا ہمیں فوری طور پر اس کے بارے میں بتائے گا۔ مثال کے طور پر:
public static class Parent {
        public void method() {
            System.out.println("parent");
        }
}
public static class Child extends Parent {
        @Override
        public void method(String text) {
            System.out.println("child");
        }
}
غلطی کے ساتھ مرتب نہیں کرتا: غلطی: طریقہ سپر ٹائپ سے کسی طریقہ کو اوور رائڈ یا نافذ نہیں کرتا ہے۔
پولیمورفزم اور اس کے دوست - 6
ری ڈیفینیشن " covariance " کے تصور سے بھی وابستہ ہے ۔ آئیے ایک مثال دیکھتے ہیں:
public class HelloWorld {
    public static class Parent {
        public Number method() {
            return 1;
        }
    }
    public static class Child extends Parent {
        @Override
        public Integer method() {
            return 2;
        }
    }

    public static void main(String[] args) {
        System.out.println(new Child().method());
    }
}
بظاہر ناگواری کے باوجود، معنی اس حقیقت پر اترتا ہے کہ جب ہم اس پر عمل پیرا ہوتے ہیں، تو ہم نہ صرف اس قسم کو لوٹ سکتے ہیں جو اسلاف میں بیان کی گئی تھی، بلکہ ایک زیادہ مخصوص قسم بھی۔ مثال کے طور پر، آباؤ اجداد نے نمبر لوٹایا، اور ہم عدد کو واپس کر سکتے ہیں - نمبر کی اولاد۔ طریقہ کے تھرو میں اعلان کردہ مستثنیات پر بھی یہی لاگو ہوتا ہے۔ وارث طریقہ کو اوور رائیڈ کر سکتے ہیں اور پھینکی گئی رعایت کو بہتر کر سکتے ہیں۔ لیکن وہ پھیل نہیں سکتے۔ یعنی، اگر والدین ایک IOException پھینکتے ہیں، تو ہم زیادہ درست EOFException پھینک سکتے ہیں، لیکن ہم ایک استثنا نہیں پھینک سکتے۔ اسی طرح، آپ دائرہ کار کو کم نہیں کر سکتے اور آپ اضافی پابندیاں نہیں لگا سکتے۔ مثال کے طور پر، آپ جامد شامل نہیں کر سکتے ہیں۔
پولیمورفزم اور اس کے دوست - 7

چھپا

" چھپانا " جیسی چیز بھی ہے ۔ مثال:
public class HelloWorld {
    public static class Parent {
        public static void method() {
            System.out.println("Parent");
        }
    }
    public static class Child extends Parent {
        public static void method() {
            System.out.println("Child");
        }
    }

    public static void main(String[] args) {
        Parent parent = new Parent();
        Parent child = new Child();
        parent.method();
        child.method();
    }
}
اگر آپ اس کے بارے میں سوچتے ہیں تو یہ ایک بہت واضح چیز ہے۔ کلاس کے جامد ممبران کا تعلق کلاس سے ہے، یعنی متغیر کی قسم تک۔ لہذا، یہ منطقی ہے کہ اگر بچہ والدین کی قسم کا ہے، تو طریقہ والدین کو پکارا جائے گا، بچے پر نہیں۔ اگر ہم بائی کوڈ کو دیکھیں، جیسا کہ ہم نے پہلے کیا تھا، تو ہم دیکھیں گے کہ جامد طریقہ کو invokestatic کا استعمال کرتے ہوئے کہا جاتا ہے۔ یہ JVM کی وضاحت کرتا ہے کہ اسے قسم کو دیکھنے کی ضرورت ہے، نہ کہ طریقہ کار کی میز پر، جیسا کہ invokevirtual یا invokeinterface نے کیا تھا۔
پولیمورفزم اور اس کے دوست - 8

اوورلوڈنگ کے طریقے

جاوا اوریکل ٹیوٹوریل میں ہم اور کیا دیکھتے ہیں؟ پہلے زیر مطالعہ سیکشن " طریقوں کی تعریف " میں اوور لوڈنگ کے بارے میں کچھ ہے۔ یہ کیا ہے؟ روسی میں یہ "طریقہ اوورلوڈنگ" ہے، اور ایسے طریقوں کو "اوور لوڈنگ" کہا جاتا ہے۔ تو، طریقہ اوورلوڈنگ. پہلی نظر میں، سب کچھ آسان ہے. آئیے ایک آن لائن جاوا کمپائلر کھولتے ہیں، مثال کے طور پر tutorialspoint online java compiler ۔
public class HelloWorld {

	public static void main(String []args){
		HelloWorld hw = new HelloWorld();
		hw.say(1);
		hw.say("1");
	}

	public static void say(Integer number) {
		System.out.println("Integer " + number);
	}
	public static void say(String number) {
		System.out.println("String " + number);
	}
}
لہذا، یہاں سب کچھ آسان لگتا ہے. جیسا کہ اوریکل ٹیوٹوریل میں بتایا گیا ہے، اوور لوڈ شدہ طریقے (اس معاملے میں کہنے کا طریقہ) طریقہ کو پاس کیے گئے دلائل کی تعداد اور قسم میں مختلف ہیں۔ آپ ایک ہی نام اور ایک جیسی تعداد کے دلائل کا اعلان نہیں کر سکتے، کیونکہ مرتب کرنے والا انہیں ایک دوسرے سے ممتاز نہیں کر سکے گا۔ یہ ایک بہت اہم چیز کو فوری طور پر نوٹ کرنے کے قابل ہے:
پولیمورفزم اور اس کے دوست - 9
یعنی اوور لوڈنگ کے وقت کمپائلر درستگی کی جانچ کرتا ہے۔ یہ ضروری ہے کہ. لیکن مرتب کرنے والا دراصل یہ کیسے طے کرتا ہے کہ کسی خاص طریقہ کو بلانے کی ضرورت ہے؟ یہ جاوا زبان کی تفصیلات میں بیان کردہ "انتہائی مخصوص طریقہ" کے اصول کا استعمال کرتا ہے: " 15.12.2.5. انتہائی مخصوص طریقہ کا انتخاب "۔ یہ ظاہر کرنے کے لیے کہ یہ کیسے کام کرتا ہے، آئیے اوریکل سرٹیفائیڈ پروفیشنل جاوا پروگرامر سے ایک مثال لیتے ہیں:
public class Overload{
  public void method(Object o) {
    System.out.println("Object");
  }
  public void method(java.io.FileNotFoundException f) {
    System.out.println("FileNotFoundException");
  }
  public void method(java.io.IOException i) {
    System.out.println("IOException");
  }
  public static void main(String args[]) {
    Overload test = new Overload();
    test.method(null);
  }
}
یہاں سے ایک مثال لیں: https://github.com/stokito/OCPJP/blob/master/src/ru/habrahabr/blogs/java/OCPJP1/question1/Overload.j... جیسا کہ آپ دیکھ سکتے ہیں، ہم گزر رہے ہیں طریقہ کار کو کالعدم کمپائلر سب سے مخصوص قسم کا تعین کرنے کی کوشش کرتا ہے۔ اعتراض مناسب نہیں ہے کیونکہ سب کچھ اس سے وراثت میں ملا ہے. آگے بڑھو. مستثنیات کی 2 کلاسیں ہیں۔ آئیے java.io.IOException کو دیکھیں اور دیکھیں کہ "Direct Known Subclasses" میں FileNotFoundException موجود ہے۔ یعنی، یہ پتہ چلتا ہے کہ FileNotFoundException سب سے مخصوص قسم ہے۔ لہذا، نتیجہ سٹرنگ "FileNotFoundException" کا آؤٹ پٹ ہوگا۔ لیکن اگر ہم IOException کو EOFException سے تبدیل کرتے ہیں، تو پتہ چلتا ہے کہ ہمارے پاس ٹائپ ٹری میں درجہ بندی کی ایک ہی سطح پر دو طریقے ہیں، یعنی ان دونوں کے لیے، IOException پیرنٹ ہے۔ مرتب کرنے والا یہ انتخاب نہیں کر سکے گا کہ کس طریقہ کو کال کرنا ہے اور تالیف کی غلطی پھینک دے گا: reference to method is ambiguous. ایک اور مثال:
public class Overload{
    public static void method(int... array) {
        System.out.println("1");
    }

    public static void main(String args[]) {
        method(1, 2);
    }
}
یہ 1 آؤٹ پٹ کرے گا۔ یہاں کوئی سوال نہیں ہیں۔ قسم int... ایک ورارگ https://docs.oracle.com/javase/8/docs/technotes/guides/language/varargs.html ہے اور واقعی "نحوی شوگر" سے زیادہ کچھ نہیں ہے اور حقیقت میں ایک int ہے۔ .. array کو int[] array کے طور پر پڑھا جا سکتا ہے۔ اگر ہم اب ایک طریقہ شامل کریں:
public static void method(long a, long b) {
	System.out.println("2");
}
پھر یہ 1 نہیں بلکہ 2 ظاہر کرے گا کیونکہ ہم 2 نمبر پاس کر رہے ہیں، اور 2 دلائل ایک صف سے بہتر میچ ہیں۔ اگر ہم ایک طریقہ شامل کریں:
public static void method(Integer a, Integer b) {
	System.out.println("3");
}
پھر ہم اب بھی 2 دیکھیں گے۔ کیونکہ اس معاملے میں پرائمیٹوز انٹیجر میں باکسنگ سے زیادہ درست میچ ہیں۔ تاہم، اگر ہم عمل کرتے ہیں، method(new Integer(1), new Integer(2));تو یہ 3 پرنٹ کرے گا۔ جاوا میں کنسٹرکٹرز طریقوں سے ملتے جلتے ہیں، اور چونکہ انہیں دستخط حاصل کرنے کے لیے بھی استعمال کیا جا سکتا ہے، اسی لیے "اوور لوڈنگ ریزولوشن" کے اصول ان پر اوور لوڈ شدہ طریقوں کے طور پر لاگو ہوتے ہیں۔ جاوا زبان کی تفصیلات ہمیں " 8.8.8. کنسٹرکٹر اوور لوڈنگ " میں بتاتی ہیں۔ طریقہ اوورلوڈ = ارلی بائنڈنگ (عرف سٹیٹک بائنڈنگ) آپ اکثر ابتدائی اور دیر سے بائنڈنگ کے بارے میں سن سکتے ہیں، جسے سٹیٹک بائنڈنگ یا ڈائنامک بائنڈنگ بھی کہا جاتا ہے۔ ان کے درمیان فرق بہت آسان ہے۔ ابتدائی طور پر تالیف ہے، دیر سے وقت ہے جب پروگرام کو انجام دیا جاتا ہے. لہذا، ابتدائی بائنڈنگ (سٹیٹک بائنڈنگ) اس بات کا تعین ہے کہ تالیف کے وقت کس کو کس پر بلایا جائے گا۔ ٹھیک ہے، لیٹ بائنڈنگ (ڈائنیمک بائنڈنگ) اس بات کا تعین ہے کہ پروگرام کے عمل کے وقت براہ راست کس طریقہ کو کال کرنا ہے۔ جیسا کہ ہم نے پہلے دیکھا تھا (جب ہم نے IOException کو EOFException میں تبدیل کیا تھا)، اگر ہم طریقوں کو اوورلوڈ کرتے ہیں تاکہ کمپائلر یہ نہ سمجھ سکے کہ کون سی کال کہاں کرنی ہے، تو ہمیں کمپائل ٹائم ایرر ملے گا: طریقہ کا حوالہ مبہم ہے۔ انگریزی سے ترجمہ شدہ لفظ ابہام کا مطلب ہے مبہم یا غیر یقینی، غلط۔ یہ پتہ چلتا ہے کہ اوورلوڈ ابتدائی پابند ہے، کیونکہ چیک مرتب وقت پر کیا جاتا ہے۔ اپنے نتائج کی تصدیق کرنے کے لیے، آئیے باب " 8.4.9. اوورلوڈنگ " میں جاوا لینگویج سپیکیفیکیشن کو کھولتے ہیں:
پولیمورفزم اور اس کے دوست - 10
یہ پتہ چلتا ہے کہ تالیف کے دوران، طریقہ کے دستخط کا تعین کرنے کے لئے دلائل کی اقسام اور تعداد کے بارے میں معلومات (جو تالیف کے وقت دستیاب ہے) کا استعمال کیا جائے گا. اگر طریقہ آبجیکٹ کے طریقوں میں سے ایک ہے (یعنی مثال کا طریقہ)، تو اصل طریقہ کال کا تعین رن ٹائم پر ڈائنامک میتھڈ لوک اپ (یعنی ڈائنامک بائنڈنگ) کا استعمال کرتے ہوئے کیا جائے گا۔ اس کو واضح کرنے کے لیے، آئیے ایک مثال لیتے ہیں جو پہلے زیر بحث کی طرح ہے۔
public class HelloWorld {
    public void method(int intNumber) {
        System.out.println("intNumber");
    }
    public void method(Integer intNumber) {
        System.out.println("Integer");
    }
    public void method(String intNumber) {
        System.out.println("Number is: " + intNumber);
    }

    public static void main(String args[]) {
        HelloWorld test = new HelloWorld();
        test.method(2);
    }
}
آئیے اس کوڈ کو HelloWorld.java فائل میں محفوظ کریں اور اسے استعمال کرکے مرتب کریں javac HelloWorld.java اب آئیے دیکھتے ہیں کہ ہمارے کمپائلر نے کمانڈ کو چلا کر بائٹ کوڈ میں کیا لکھا ہے javap -verbose HelloWorld۔
پولیمورفزم اور اس کے دوست - 11
جیسا کہ کہا گیا ہے، مرتب کرنے والے نے طے کیا ہے کہ مستقبل میں کچھ ورچوئل طریقہ بلایا جائے گا۔ یعنی رن ٹائم کے وقت طریقہ کار کی وضاحت کی جائے گی۔ لیکن تالیف کے وقت، تینوں طریقوں میں سے، مرتب کرنے والے نے سب سے موزوں طریقہ کا انتخاب کیا، تو اس نے نمبر کی نشاندہی کی:"invokevirtual #13"
پولیمورفزم اور اس کے دوست - 12
یہ کس قسم کا طریقہ کار ہے؟ یہ طریقہ کار کا لنک ہے۔ موٹے الفاظ میں، یہ کچھ اشارہ ہے جس کے ذریعے، رن ٹائم پر، جاوا ورچوئل مشین دراصل اس بات کا تعین کر سکتی ہے کہ عمل کرنے کے لیے کون سا طریقہ تلاش کرنا ہے۔ مزید تفصیلات سپر آرٹیکل میں مل سکتی ہیں: " JVM اندرونی طور پر اوور لوڈنگ اور اوور رائیڈنگ کو کیسے ہینڈل کرتا ہے

خلاصہ کرنا

لہذا، ہمیں پتہ چلا کہ جاوا، ایک آبجیکٹ پر مبنی زبان کے طور پر، پولیمورفزم کی حمایت کرتا ہے۔ پولیمورفزم جامد (سٹیٹک بائنڈنگ) یا ڈائنامک (ڈائنامک بائنڈنگ) ہوسکتا ہے۔ جامد پولیمورفزم کے ساتھ، جسے ابتدائی بائنڈنگ بھی کہا جاتا ہے، مرتب کرنے والا طے کرتا ہے کہ کس طریقہ کو اور کہاں کہا جانا چاہیے۔ یہ اوورلوڈ جیسے میکانزم کے استعمال کی اجازت دیتا ہے۔ ڈائنامک پولیمورفزم کے ساتھ، جسے لیٹ بائنڈنگ کے نام سے بھی جانا جاتا ہے، کسی طریقہ کے پہلے حساب شدہ دستخط کی بنیاد پر، رن ٹائم کے وقت ایک طریقہ کا حساب لگایا جائے گا اس بنیاد پر کہ کس چیز کو استعمال کیا گیا ہے (یعنی، کس چیز کا طریقہ کہا جاتا ہے)۔ یہ میکانزم کیسے کام کرتے ہیں بائٹ کوڈ کا استعمال کرتے ہوئے دیکھا جا سکتا ہے۔ اوورلوڈ طریقہ کار کے دستخطوں کو دیکھتا ہے، اور اوورلوڈ کو حل کرتے وقت، سب سے مخصوص (سب سے زیادہ درست) آپشن کا انتخاب کیا جاتا ہے۔ اوور رائیڈنگ اس قسم کو دیکھتا ہے کہ کون سے طریقے دستیاب ہیں، اور طریقوں کو خود اعتراض کی بنیاد پر کہا جاتا ہے۔ نیز موضوع پر مواد: #ویاچسلاو
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION