2017-11-23 29 views
5

मैंने कुछ लेखों के माध्यम से स्थिर बाध्यकारी और जावा में गतिशील बाध्यकारी के बारे में कुछ लेख पढ़े हैं। और मैं निम्नलिखित प्रश्न (मैं एक बहुत खोज की है, लेकिन इसके बारे में अभी तक नहीं मिला कोई उल्लेख है):जावा में स्थिर बाध्यकारी और गतिशील बाध्यकारी के साथ समस्याएं

उदाहरण के लिए, मैं कोड की निम्न पंक्तियाँ:

Person a = new Student(); // Student is a subclass of Person 
a.speak(); 

हम क्या ' पहले से ही ज्ञात है कि संकलन-समय पर, संकलक जांच करेगा कि speak() के लिए Person में विधि परिभाषा मौजूद है या नहीं, और यदि यह मौजूद है तो इसे कॉल करें। और रन-टाइम में, यह वास्तविक वस्तु जो करने के लिए a इशारा कर रही है की speak() विधि कॉल करेंगे (इस मामले में वास्तविक वस्तु स्पष्ट रूप से Student है)

तो मेरे सवाल वजह है कि यह सीधे कॉल नहीं करता speak() कक्षा Studentसंकलन समय पर विधि, लेकिन रन-टाइम तक प्रतीक्षा करें? क्या इसके पीछे कोई कारण हैं?

+0

क्योंकि आपके सॉफ़्टवेयर को संकलित करना इसे चलाने से अलग है। –

+0

क्योंकि * आपने * कंपाइलर को बताया कि 'ए' को' छात्र 'के बजाय' व्यक्ति 'के रूप में माना जाना चाहिए। और अनुरोध के मुकाबले कोड को अलग तरीके से क्यों संकलित करना चाहिए? आप उस अलग रणनीति के लिए क्या लाभ उठा रहे हैं? – Holger

उत्तर

3

जब कोड संकलित होता है, कभी-कभी, यह स्पष्ट नहीं होता कि कौन सी विधि को लागू करने की आवश्यकता है। इसे केवल रनटाइम पर ही निर्धारित किया जा सकता है।

इस सरल कोड को एक उदाहरण के रूप में लें।

class Animal{ 

    public void makeNoise(){ 
     System.out.println("Default"); 
    }; 
} 

class Dog extends Animal{ 

    //override the makeNoise() 
    public void makeNoise(){ 
     System.out.println("Woof"); 
    }; 
} 

class Cat extends Animal{ 

     //override the makeNoise() 
     public void makeNoise(){ 
      System.out.println("Meow"); 
     }; 
    } 

public class Sounds{ 

    public static void AnimalSounds(Animal animal){ 
    animal.makeNoise(); 
    } 

    public static void main(String args[]){ 

     Animal dog = new Dog();  
     Animal cat = new Cat(); 
     AnimalSounds(dog); 
     AnimalSounds(cat); 
    } 
} 

AnimalSounds(Animal animal) विधि किसी भी वस्तु है कि पशु की ISA परीक्षण गुजरता है और उस वस्तु के संबंधित विधि आह्वान लेता है। जैसा कि आप देख सकते हैं, यह कोड डुप्लिकेशन को भी हटा देता है क्योंकि हम विभिन्न प्रकार की वस्तुओं पर एक ही विधि का उपयोग कर सकते हैं।

आशा है कि यह आपकी चिंता का समाधान करे।

+0

पहले धन्यवाद। लेकिन क्या आप ऊपर दिए गए उदाहरण पर "कभी-कभी, यह स्पष्ट नहीं है कि किस विधि को लागू करने की आवश्यकता है" पर कुछ विवरण प्रदान कर सकते हैं? – DunDev

+0

animal.makeNoise(); यहां, संकलन समय पर यह वस्तु के प्रकार के बारे में ज्ञात नहीं है। रन टाइम पर, आप एक विशेष पशु वस्तु को पार करते हैं और उस पर आधारित, यह उस जानवर के संबंधित तरीके को आमंत्रित करता है (उदा: कुत्ते या बिल्ली) –

3

इस विषय को समझने के लिए आपको पता होना चाहिए कि आम तौर पर संकलन और रन-टाइम प्रक्रियाएं क्या होती हैं। संक्षेप में, जब आप अपना ऐप कंपाइलर बनाते हैं तो आपके सभी कोड और स्थिरता, सुरक्षा और रन-योग्यता के लिए जांच करता है। यदि कंपाइलर द्वारा स्थापित कोई त्रुटि नहीं है तो यह आपके स्रोत कोड (java फ़ाइलों) से class फ़ाइलों को उत्पन्न करता है। जब ऐप चल रहा है तो इसका मतलब है कि आपकी class फ़ाइलें स्मृति में लोड की गई हैं और JVM निर्देश द्वारा आपके ऐप निर्देश को निष्पादित कर रहा है।

अपने उदाहरण से:

Person a = new Student(); // Student is a subclass of Person 
a.speak();  

संकलन प्रक्रिया: संकलक चेकों इस लाइन: प्रकार की सुरक्षा (संगतता) के लिए Person a = new Student();। इसलिए, यदि छात्र is a व्यक्ति संकलन अगली पंक्ति में जाता है तो यह विफल हो जाता है। अगली पंक्ति में: a.speak(); कंपाइलर a प्रकार पर दिखता है, यह पाया गया कि यह Person है और विधि Person प्रकार पर देखता है। यदि संकलक संकलन प्रक्रिया द्वारा स्थापित की गई विधि विफल नहीं होती है।

रनटाइम प्रक्रिया: जब JVM इस लाइन को निष्पादित करता है: Person a = new Student(); यह जाता है आरंभीकरण प्रक्रिया के माध्यम से शीर्ष (मूल वर्ग) से नीचे (बच्चे वर्ग) के लिए।अगली पंक्ति में: a.speak(); JVM संदर्भ a के माध्यम से विधि में स्थापित किया गया है, तो इसे निष्पादित करता है, अन्यथा यह speak() विधि को पेरेंट क्लास Person से चलाता है।

विरासत विषय से एक और उदाहरण:

class Person { 
    public void speak() {} 
    public void think() {} 
} 

class Student extends Person { 
    @Override 
    public void speak() {} 
    public void speakALot() {} 
} 

Person a = new Student(); 
a.speak(); // calling overrided version of speak() 
a.think(); // since this method is not overrided in child class it will be called from parent class 
a.speakALot(); // since Person doesn't know anything about specific methods of derived classes compilation fails 

Student b = new Student(); 
b.speak(); // calling speak() method of student object 
b.think(); // inheritance trick, child class keeps reference to its base class and that's why public and protected fields and methods are available 
b.speakALot(); // calling speakALot() method of student object 
+0

धन्यवाद, आप एक महान स्पष्टीकरण दे रहे हैं .. लेकिन मेरे पास एक सवाल है, मैं मैं जावाटपॉइंट टूरियल से जावा का अध्ययन कर रहा हूं, और इस लिंक से [स्थिर बाध्यकारी और गतिशील बाध्यकारी] (https://www.javatpoint.com/static-binding-and- गतिशील- बाइंडिंग) मुझे समझ में आया है कि बाध्यकारी ऑपरेशन है विधि पद्धति में एक विधि कॉल को जोड़ना, लेकिन मुझे कुछ मामलों को समझने में कुछ परेशानी हो रही है, जैसे कि आपके उदाहरण में आप प्रत्येक विधि कॉल के लिए बाध्यकारी प्रकार जोड़ने के लिए उत्तर संपादित कर सकते हैं? या यहां भी लिखो। –

+1

इस पर एक नज़र डालें [ट्यूटोरियल] (http://javaconceptoftheday.com/static-binding-and-dynamic-binding-in-java/) पहले। यदि आपके पास कोई प्रश्न होगा तो मैं अपना उत्तर – jibrahim

+0

अपडेट कर दूंगा, मेरा मानना ​​है कि यह प्रश्न निर्धारित करेगा कि क्या मैं इसे सही समझता हूं या नहीं .. क्या इसका मतलब स्थिर और गतिशील बाध्यकारी कदम हैं (विकल्प नहीं), और उनमें से दोनों हो सकते हैं विधि निकाय को निर्धारित करने के लिए एक ही विधि कॉल कहा जाना चाहिए ?? –

0

मैं सिर्फ वाहन के रूप में इस प्रकार के किसी भी प्रकार का परीक्षण करने के एक सामान्य प्रयोजन वर्ग लिखते हैं।

public class Workshop{ 
    public boolean test(Vehicle vehicle){ 
     vehicle.start(); 
     vehicle.stop(); 
     //...more code 
     return true; 
    } 
} 

मैं इस कोड को केवल वाहन प्रकार के साथ संकलित कर सकता हूं, हालांकि वाहन के किसी भी बच्चे वर्ग को लिखा नहीं गया है। सामान्य ढांचे में ठोस प्रकारों की अनुपस्थिति में जेनेरिक प्रकार के आधार पर प्रसंस्करण प्रदान करने की इस क्षमता का फायदा उठाते हैं (ग्राहक बाल वर्ग पदानुक्रम का विस्तार करने के लिए स्वतंत्र हैं)। ऐसे मामलों में कंपाइलर केवल यह सुनिश्चित करेगा कि वाहन में कम से कम एक कार्यान्वयन होगा ({null कार्यान्वयन जैसे {} भी स्वीकार्य है) ताकि कोड तोड़ने के लिए उपलब्ध न हो।

संबंधित मुद्दे