CodeGym /Java Blog /यादृच्छिक /जावा पॉलिमॉर्फिझम
John Squirrels
पातळी 41
San Francisco

जावा पॉलिमॉर्फिझम

यादृच्छिक या ग्रुपमध्ये प्रकाशित केले
OOP-संबंधित प्रश्न हे आयटी कंपनीत जावा डेव्हलपर पदासाठी तांत्रिक मुलाखतीचा अविभाज्य भाग आहेत. या लेखात, आपण OOP च्या एका तत्त्वाबद्दल बोलू - बहुरूपता. आम्ही मुलाखती दरम्यान ज्या पैलूंबद्दल विचारले जाते त्यावर लक्ष केंद्रित करू आणि स्पष्टतेसाठी काही उदाहरणे देखील देऊ.

जावा मध्ये पॉलिमॉर्फिझम म्हणजे काय?

पॉलीमॉर्फिझम ही एक प्रोग्रामची क्षमता आहे जी ऑब्जेक्टच्या विशिष्ट प्रकाराबद्दल माहिती न देता समान इंटरफेससह त्याच प्रकारे हाताळण्याची क्षमता आहे. पॉलिमॉर्फिझम म्हणजे काय या प्रश्नाचे उत्तर दिल्यास, बहुधा तुम्हाला काय म्हणायचे आहे ते स्पष्ट करण्यास सांगितले जाईल. अतिरिक्त प्रश्नांचा एक समूह सुरू न करता, हे सर्व पुन्हा एकदा मुलाखतकारासाठी मांडा. मुलाखतीची वेळ: जावामधील बहुरूपता - १तुम्ही या वस्तुस्थितीपासून सुरुवात करू शकता की OOP पध्दतीमध्ये क्लासेसवर आधारित ऑब्जेक्ट्समधील परस्परसंवादावर आधारित Java प्रोग्राम तयार करणे समाविष्ट आहे. वर्ग हे आधी लिहिलेले ब्ल्यूप्रिंट (टेम्प्लेट) प्रोग्राममध्ये ऑब्जेक्ट्स तयार करण्यासाठी वापरले जातात. शिवाय, वर्गामध्ये नेहमीच विशिष्ट प्रकार असतो, ज्यामध्ये चांगल्या प्रोग्रामिंग शैलीसह, त्याचे उद्देश सूचित करणारे नाव असते. पुढे, हे लक्षात घेतले जाऊ शकते की जावा जोरदार टाईप केलेला असल्याने, जेव्हा व्हेरिएबल्स घोषित केले जातात तेव्हा प्रोग्राम कोडने नेहमी ऑब्जेक्ट प्रकार निर्दिष्ट केला पाहिजे. यात हे तथ्य जोडा की कठोर टायपिंग कोडची सुरक्षा आणि विश्वासार्हता सुधारते आणि विसंगततेच्या प्रकारांमुळे (उदाहरणार्थ, स्ट्रिंगला एका संख्येने विभाजित करण्याचा प्रयत्न) त्रुटी टाळण्यासाठी संकलन करताना देखील शक्य करते. स्वाभाविकच, कंपाइलरला "माहित" असणे आवश्यक आहे घोषित प्रकार - तो JDK मधील वर्ग किंवा आम्ही स्वतः तयार केलेला वर्ग असू शकतो. आमचा कोड केवळ घोषणेमध्ये दर्शविलेल्या प्रकारच्या वस्तूच नव्हे तर त्याचे वंशज देखील वापरू शकतो हे मुलाखतकर्त्याला सूचित करा.हा एक महत्त्वाचा मुद्दा आहे: आम्ही एकच प्रकार म्हणून बर्‍याच वेगवेगळ्या प्रकारांसह कार्य करू शकतो (जर हे प्रकार मूळ प्रकारातून घेतलेले असतील). याचा अर्थ असा आहे की जर आपण व्हेरिएबल घोषित केला ज्याचा प्रकार सुपरक्लास आहे, तर आपण त्या व्हेरिएबलला त्याच्या वंशजांपैकी एक उदाहरण देऊ शकतो. तुम्ही उदाहरण दिले तर मुलाखत घेणाऱ्याला ते आवडेल. काही वर्ग निवडा जे अनेक वर्गांद्वारे सामायिक केले जाऊ शकतात (त्यासाठी आधार वर्ग) आणि त्यापैकी काहींना त्याचा वारसा बनवा. बेस क्लास:

public class Dancer {
    private String name;
    private int age;

    public Dancer(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void dance() {
        System.out.println(toString() + " I dance like everyone else.");
    }

    @Override
    public String toString() {
        Return "I'm " + name + ". I'm " + age + " years old.";
    }
}
उपवर्गांमध्ये, बेस क्लासची पद्धत ओव्हरराइड करा:

public class ElectricBoogieDancer extends Dancer {
    public ElectricBoogieDancer(String name, int age) {
        super(name, age);
    }
// Override the method of the base class
    @Override
    public void dance() {
        System.out.println(toString () + " I dance the electric boogie!");
    }
}

public class Breakdancer extends Dancer {

    public Breakdancer(String name, int age) {
        super(name, age);
    }
// Override the method of the base class
    @Override
    public void dance() {
        System.out.println(toString() + " I breakdance!");
    }
}
पॉलिमॉर्फिझमचे उदाहरण आणि प्रोग्राममध्ये या वस्तू कशा वापरल्या जाऊ शकतात:

public class Main {

    public static void main(String[] args) {
        Dancer dancer = new Dancer("Fred", 18);

        Dancer breakdancer = new Breakdancer("Jay", 19); // Widening conversion to the base type 
        Dancer electricBoogieDancer = new ElectricBoogieDancer("Marcia", 20); // Widening conversion to the base type

        List<dancer> disco = Arrays.asList(dancer, breakdancer, electricBoogieDancer);
        for (Dancer d : disco) {
            d.dance(); // Call the polymorphic method
        }
    }
}
मुख्य पद्धतीमध्ये , त्या ओळी दाखवा

Dancer breakdancer = new Breakdancer("Jay", 19);
Dancer electricBoogieDancer = new ElectricBoogieDancer("Marcia", 20);
सुपरक्लासचे व्हेरिएबल घोषित करा आणि त्याला एक ऑब्जेक्ट नियुक्त करा जे त्याच्या वंशजांपैकी एकाचे उदाहरण आहे. असाइनमेंट ऑपरेटरच्या डाव्या आणि उजव्या बाजूला घोषित केलेल्या प्रकारांच्या विसंगतीवर कंपाइलर का फ्लिप आउट करत नाही असे तुम्हाला बहुधा विचारले जाईल — शेवटी, Java जोरदार टाइप केले आहे. स्पष्ट करा की रुंदीकरण प्रकाराचे रूपांतरण येथे कार्यरत आहे — एखाद्या वस्तूचा संदर्भ त्याच्या बेस क्लासच्या संदर्भाप्रमाणे हाताळला जातो. इतकेच काय, कोडमध्ये अशी रचना आढळल्यावर, कंपाइलर आपोआप आणि अस्पष्टपणे रूपांतरण करतो. नमुना कोड दर्शवितो की असाइनमेंट ऑपरेटरच्या डाव्या बाजूला घोषित केलेल्या प्रकारात ( डान्सर ) एकाधिक फॉर्म (प्रकार) आहेत, जे उजव्या बाजूला घोषित केले जातात ( ब्रेकडान्सर , इलेक्ट्रिकबुगी डान्सर). सुपरक्लास ( नृत्य पद्धत) मध्ये परिभाषित केलेल्या सामान्य कार्यक्षमतेच्या संदर्भात प्रत्येक फॉर्मचे स्वतःचे वेगळे वर्तन असू शकते . म्हणजेच, सुपरक्लासमध्ये घोषित केलेली पद्धत त्याच्या वंशजांमध्ये वेगळ्या प्रकारे लागू केली जाऊ शकते. या प्रकरणात, आम्ही पद्धत ओव्हरराइडिंगचा सामना करत आहोत, जे एकापेक्षा जास्त फॉर्म (वर्तणूक) तयार करते. हे मुख्य पद्धतीमध्ये कोड चालवून पाहिले जाऊ शकते: प्रोग्राम आउटपुट: मी फ्रेड आहे. मी 18 वर्षांचा आहे. मी इतरांप्रमाणे नाचतो. मी जय. मी १९ वर्षांचा आहे. मी ब्रेकडान्स! मी मार्सिया आहे. मी 20 वर्षाचा आहे. मी इलेक्ट्रिक बूगी नाचतो! जर आपण उपवर्गांमध्ये पद्धत ओव्हरराइड केली नाही, तर आपल्याला भिन्न वर्तन मिळणार नाही. उदाहरणार्थ,ElectricBoogieDancer वर्ग, नंतर प्रोग्रामचे आउटपुट असे असेल: मी फ्रेड आहे. मी 18 वर्षांचा आहे. मी इतरांप्रमाणे नाचतो. मी जय. मी १९ वर्षांचा आहे. मी इतरांप्रमाणे नाचतो. मी मार्सिया आहे. मी 20 वर्षाचा आहे. मी इतरांप्रमाणे नाचतो. आणि याचा अर्थ असा की ब्रेकडान्सर आणि इलेक्ट्रिक बूगी डान्सर वर्ग तयार करण्यात अर्थ नाही . विशेषत: बहुरूपतेचे तत्त्व कोठे प्रकट होते? प्रोग्राममध्ये एखादी वस्तू त्याच्या विशिष्ट प्रकाराची माहिती नसताना कुठे वापरली जाते? आमच्या उदाहरणात, जेव्हा डान्सर डी ऑब्जेक्टवर डान्स() पद्धत कॉल केली जाते तेव्हा असे होते . जावामध्ये, पॉलीमॉर्फिझम म्हणजे प्रोग्रामला ऑब्जेक्ट ए आहे की नाही हे माहित असणे आवश्यक नाही ब्रेकडान्सर किंवा इलेक्ट्रिक बूगी डान्सर . महत्त्वाची गोष्ट म्हणजे ती डान्सर वर्गाची वंशज आहे. आणि जर तुम्ही वंशजांचा उल्लेख केला तर तुम्ही लक्षात घ्या की जावा मधील वारसा केवळ विस्तारित नाही तर अंमलबजावणी देखील आहे.. आता हे नमूद करण्याची वेळ आली आहे की जावा एकाधिक वारसास समर्थन देत नाही — प्रत्येक प्रकारात एक पालक (सुपरक्लास) आणि अमर्यादित वंशज (उपवर्ग) असू शकतात. त्यानुसार, वर्गांमध्ये फंक्शन्सचे अनेक संच जोडण्यासाठी इंटरफेसचा वापर केला जातो. उपवर्ग (वारसा) च्या तुलनेत, इंटरफेस पालक वर्गाशी कमी जोडलेले आहेत. ते खूप मोठ्या प्रमाणावर वापरले जातात. Java मध्ये, इंटरफेस हा संदर्भ प्रकार आहे, त्यामुळे प्रोग्राम इंटरफेस प्रकाराचे व्हेरिएबल घोषित करू शकतो. आता उदाहरण देण्याची वेळ आली आहे. इंटरफेस तयार करा:

public interface CanSwim {
    void swim();
}
स्पष्टतेसाठी, आम्ही विविध असंबंधित वर्ग घेऊ आणि त्यांना इंटरफेस लागू करू:

public class Human implements CanSwim {
    private String name;
    private int age;

    public Human(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public void swim() {
        System.out.println(toString()+" I swim with an inflated tube.");
    }

    @Override
    public String toString() {
        return "I'm " + name + ". I'm " + age + " years old.";
    }

}
 
public class Fish implements CanSwim {
    private String name;

    public Fish(String name) {
        this.name = name;
    }

    @Override
    public void swim() {
        System.out.println("I'm a fish. My name is " + name + ". I swim by moving my fins.");

    }

public class UBoat implements CanSwim {

    private int speed;

    public UBoat(int speed) {
        this.speed = speed;
    }

    @Override
    public void swim() {
        System.out.println("I'm a submarine that swims through the water by rotating screw propellers. My speed is " + speed + " knots.");
    }
}
मुख्य पद्धत:

public class Main {

    public static void main(String[] args) {
        CanSwim human = new Human("John", 6);
        CanSwim fish = new Fish("Whale");
        CanSwim boat = new UBoat(25);

        List<swim> swimmers = Arrays.asList(human, fish, boat);
        for (Swim s : swimmers) {
            s.swim();
        }
    }
}
इंटरफेसमध्ये परिभाषित केलेल्या पॉलिमॉर्फिक पद्धतीला कॉल करणारे परिणाम आम्हाला या इंटरफेसची अंमलबजावणी करणार्‍या प्रकारांच्या वर्तनातील फरक दर्शवतात. आमच्या बाबतीत, हे पोहण्याच्या पद्धतीद्वारे प्रदर्शित केलेले भिन्न तार आहेत. आमच्‍या उदाहरणाचा अभ्यास केल्‍यानंतर, मुलाखतकार विचारू शकतो की हा कोड मुख्‍य पद्धतीत का चालवायचा

for (Swim s : swimmers) {
            s.swim();        
}
आमच्या उपवर्गांमध्ये परिभाषित केलेल्या ओव्हरराइडिंग पद्धती म्हणतात का? प्रोग्राम चालू असताना पद्धतीची इच्छित अंमलबजावणी कशी निवडली जाते? या प्रश्नांची उत्तरे देण्यासाठी, तुम्हाला उशीरा (डायनॅमिक) बंधन स्पष्ट करणे आवश्यक आहे. बाइंडिंग म्हणजे मेथड कॉल आणि त्याची विशिष्ट वर्ग अंमलबजावणी दरम्यान मॅपिंग स्थापित करणे. थोडक्यात, वर्गांमध्ये परिभाषित केलेल्या तीन पद्धतींपैकी कोणती कार्यान्वित केली जाईल हे कोड निर्धारित करते. Java डीफॉल्टनुसार उशीरा बाइंडिंग वापरते, म्हणजे बाइंडिंग रनटाइमवर होते आणि कंपाइल वेळी नाही जसे लवकर बाइंडिंगच्या बाबतीत आहे. याचा अर्थ असा की जेव्हा कंपाइलर हा कोड संकलित करतो

for (Swim s : swimmers) {
            s.swim();        
}
कोणत्या वर्गात ( मानवी , मासे किंवा उबोट ) कोड आहे हे माहित नाही जे पोहल्यावर अंमलात आणले जाईलपद्धत म्हणतात. डायनॅमिक बाइंडिंग मेकॅनिझम (रनटाइमच्या वेळी ऑब्जेक्टचा प्रकार तपासणे आणि या प्रकारासाठी योग्य अंमलबजावणी निवडणे) धन्यवाद, जेव्हा प्रोग्राम कार्यान्वित केला जातो तेव्हाच हे निर्धारित केले जाते. जर तुम्हाला हे कसे अंमलात आणले जाते असे विचारले असेल, तर तुम्ही उत्तर देऊ शकता की ऑब्जेक्ट्स लोड करताना आणि इनिशियलाइज करताना, JVM मेमरीमध्ये टेबल बनवते आणि व्हेरिएबल्सला त्यांच्या मूल्यांसह आणि ऑब्जेक्ट्स त्यांच्या पद्धतींसह जोडते. असे करताना, जर एखाद्या वर्गाला वारसा मिळाला असेल किंवा इंटरफेस लागू केला असेल, तर व्यवसायाचा पहिला क्रम म्हणजे ओव्हरराइड केलेल्या पद्धतींची उपस्थिती तपासणे. जर काही असतील तर ते या प्रकाराला बांधील आहेत. तसे नसल्यास, जुळणार्‍या पद्धतीचा शोध एक पाऊल उंच असलेल्या वर्गाकडे (पालक) आणि बहुस्तरीय पदानुक्रमात रूटपर्यंत हलविला जातो. जेव्हा OOP मधील बहुरूपता आणि कोडमध्ये त्याची अंमलबजावणी येते, आम्ही लक्षात घेतो की बेस क्लासेसची अमूर्त व्याख्या प्रदान करण्यासाठी अमूर्त वर्ग आणि इंटरफेस वापरणे चांगले आहे. ही प्रथा अमूर्ततेच्या तत्त्वावर आधारित आहे - सामान्य वर्तन आणि गुणधर्म ओळखणे आणि त्यांना अमूर्त वर्गात ठेवणे किंवा केवळ सामान्य वर्तन ओळखणे आणि ते इंटरफेसमध्ये ठेवणे. पॉलीमॉर्फिझम लागू करण्यासाठी इंटरफेस आणि क्लास इनहेरिटन्सवर आधारित ऑब्जेक्ट पदानुक्रम डिझाइन करणे आणि तयार करणे आवश्यक आहे. जावामधील बहुरूपता आणि नवकल्पनांच्या संदर्भात, आम्ही लक्षात घेतो की जावा 8 पासून प्रारंभ करून, अमूर्त वर्ग आणि इंटरफेस तयार करताना ते वापरणे शक्य आहे किंवा फक्त सामान्य वर्तन ओळखणे आणि ते इंटरफेसमध्ये ठेवणे. पॉलीमॉर्फिझम लागू करण्यासाठी इंटरफेस आणि क्लास इनहेरिटन्सवर आधारित ऑब्जेक्ट पदानुक्रम डिझाइन करणे आणि तयार करणे आवश्यक आहे. जावामधील बहुरूपता आणि नवकल्पनांच्या संदर्भात, आम्ही लक्षात घेतो की जावा 8 पासून प्रारंभ करून, अमूर्त वर्ग आणि इंटरफेस तयार करताना ते वापरणे शक्य आहे किंवा फक्त सामान्य वर्तन ओळखणे आणि ते इंटरफेसमध्ये ठेवणे. पॉलीमॉर्फिझम लागू करण्यासाठी इंटरफेस आणि क्लास इनहेरिटन्सवर आधारित ऑब्जेक्ट पदानुक्रम डिझाइन करणे आणि तयार करणे आवश्यक आहे. जावामधील बहुरूपता आणि नवकल्पनांच्या संदर्भात, आम्ही लक्षात घेतो की जावा 8 पासून प्रारंभ करून, अमूर्त वर्ग आणि इंटरफेस तयार करताना ते वापरणे शक्य आहेबेस क्लासेसमधील अमूर्त पद्धतींसाठी डीफॉल्ट अंमलबजावणी लिहिण्यासाठी डीफॉल्ट कीवर्ड. उदाहरणार्थ:

public interface CanSwim {
    default void swim() {
        System.out.println("I just swim");
    }
}
कधीकधी मुलाखत घेणारे विचारतात की बेस क्लासमधील पद्धती कशा घोषित केल्या पाहिजेत जेणेकरून बहुरूपतेच्या तत्त्वाचे उल्लंघन होणार नाही. उत्तर सोपे आहे: या पद्धती स्थिर , खाजगी किंवा अंतिम नसाव्यात . खाजगी ही पद्धत केवळ वर्गामध्ये उपलब्ध करून देते, त्यामुळे तुम्ही ती उपवर्गामध्ये अधिलिखित करू शकणार नाही. स्टॅटिक कोणत्याही ऑब्जेक्टच्या ऐवजी क्लासशी पद्धत संबद्ध करते, म्हणून सुपरक्लासची पद्धत नेहमी कॉल केली जाईल. आणि अंतिम पद्धत अपरिवर्तनीय बनवते आणि उपवर्गांपासून लपविली जाते.

बहुरूपता आपल्याला काय देते?

बहुधा आपल्याला बहुधा बहुधा आपल्याला कसा फायदा होतो याबद्दल विचारले जाईल. केसाळ तपशीलांमध्ये न अडकता तुम्ही याचे थोडक्यात उत्तर देऊ शकता:
  1. हे वर्ग अंमलबजावणी पुनर्स्थित करणे शक्य करते. त्यावर चाचणी बांधली जाते.
  2. हे विस्तारक्षमता सुलभ करते, ज्यामुळे भविष्यात बांधता येईल असा पाया तयार करणे खूप सोपे होते. विद्यमान प्रकारांवर आधारित नवीन प्रकार जोडणे हा OOP प्रोग्रामची कार्यक्षमता वाढवण्याचा सर्वात सामान्य मार्ग आहे.
  3. हे तुम्हाला एका संग्रहात किंवा अॅरेमध्ये सामान्य प्रकार किंवा वर्तन सामायिक करणार्‍या वस्तू एकत्र करू देते आणि त्यांना एकसमानपणे हाताळू देते (आमच्या उदाहरणांप्रमाणे, जिथे आम्ही प्रत्येकाला नाचण्यास भाग पाडतो() किंवा पोहणे () :)
  4. नवीन प्रकार तयार करण्यात लवचिकता: तुम्ही पालकांच्या पद्धतीच्या अंमलबजावणीची निवड करू शकता किंवा उपवर्गामध्ये ती अधिलिखित करू शकता.

काही विभक्त शब्द

बहुरूपता हा एक अतिशय महत्त्वाचा आणि व्यापक विषय आहे. जावा मधील OOP वरील या लेखाच्या जवळपास अर्ध्या भागाचा हा विषय आहे आणि भाषेच्या पायाचा एक चांगला भाग आहे. तुम्ही मुलाखतीत या तत्त्वाची व्याख्या टाळू शकणार नाही. जर तुम्हाला ते माहित नसेल किंवा ते समजत नसेल, तर मुलाखत कदाचित संपेल. त्यामुळे आळशी होऊ नका - मुलाखतीपूर्वी तुमच्या ज्ञानाचे मूल्यांकन करा आणि आवश्यक असल्यास ते ताजेतवाने करा.
टिप्पण्या
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION