CodeGym/Java Blog/अनियमित/ओओपी के सिद्धांत
John Squirrels
स्तर 41
San Francisco

ओओपी के सिद्धांत

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

एक वस्तु क्या है?

हम जिस दुनिया में रहते हैं वह वस्तुओं से बनी है। चारों ओर देखते हुए, हम देख सकते हैं कि हम घरों, पेड़ों, कारों, फर्नीचर, बर्तनों और कंप्यूटरों से घिरे हुए हैं। ये सभी चीजें वस्तुएं हैं, और उनमें से प्रत्येक में विशिष्ट विशेषताओं, व्यवहारों और उद्देश्यों का एक समूह है। हम वस्तुओं के आदी हैं, और हम हमेशा उनका उपयोग बहुत विशिष्ट उद्देश्यों के लिए करते हैं। उदाहरण के लिए, यदि हमें काम पर जाने की आवश्यकता होती है, तो हम कार का उपयोग करते हैं। अगर हम खाना चाहते हैं, तो हम व्यंजन का उपयोग करते हैं। और अगर हम आराम करना चाहते हैं, तो हम एक आरामदायक सोफा ढूंढते हैं। मनुष्य दैनिक जीवन की समस्याओं को हल करने के लिए वस्तुओं के रूप में सोचने का आदी है। प्रोग्रामिंग में ऑब्जेक्ट्स का उपयोग करने का यह एक कारण है। इस दृष्टिकोण को ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग कहा जाता है। आइए एक उदाहरण देते हैं। कल्पना करें कि आपने एक नया फोन विकसित किया है और बड़े पैमाने पर उत्पादन शुरू करना चाहते हैं। फ़ोन के डेवलपर के रूप में, आप जानते हैं कि यह किस लिए है, यह कैसे कार्य करता है, और इसके भाग क्या हैं (शरीर, माइक्रोफोन, स्पीकर, तार, बटन, आदि)। क्या अधिक है, केवल आप ही जानते हैं कि इन भागों को कैसे जोड़ा जाए। लेकिन आप फोन को व्यक्तिगत रूप से बनाने की योजना नहीं बना रहे हैं - ऐसा करने के लिए आपके पास कर्मचारियों की एक पूरी टीम है। फोन के पुर्जों को जोड़ने के बारे में बार-बार समझाने की आवश्यकता को खत्म करने के लिए, और यह सुनिश्चित करने के लिए कि सभी फोन एक ही तरह से बने हैं, इससे पहले कि आप उनका उत्पादन शुरू करें, आपको एक चित्र बनाना होगा जो यह बताता हो कि फोन कैसे व्यवस्थित है। OOP में, हम ऐसे विवरण, आरेखण, आरेख या टेम्पलेट को एक वर्ग कहते हैं। जब प्रोग्राम चल रहा होता है तो यह ऑब्जेक्ट बनाने का आधार बनता है। एक वर्ग निश्चित प्रकार की वस्तुओं का विवरण है - जैसे एक सामान्य टेम्पलेट जिसमें फ़ील्ड, विधियाँ और एक निर्माता शामिल हैं। एक वस्तु एक वर्ग का एक उदाहरण है।

मतिहीनता

आइए अब इस बारे में सोचें कि हम वास्तविक दुनिया में किसी वस्तु से किसी कार्यक्रम में किसी वस्तु की ओर कैसे जा सकते हैं। हम एक उदाहरण के रूप में फ़ोन का उपयोग करेंगे। संचार के इस साधन का एक इतिहास है जो 100 से अधिक वर्षों तक फैला हुआ है। आधुनिक टेलीफोन अपने 19वीं सदी के पूर्ववर्ती की तुलना में कहीं अधिक जटिल उपकरण है। फोन का इस्तेमाल करते समय हम उसके संगठन और उसके अंदर होने वाली प्रक्रियाओं के बारे में नहीं सोचते हैं। हम बस फोन के डेवलपर्स द्वारा प्रदान किए गए कार्यों का उपयोग करते हैं: फोन नंबर दर्ज करने और कॉल करने के लिए बटन या टच स्क्रीन। पहले फोन इंटरफेस में से एक एक क्रैंक था जिसे कॉल करने के लिए घुमाने की जरूरत होती थी। बेशक, यह बहुत सुविधाजनक नहीं था। लेकिन इसने अपने कार्य को त्रुटिपूर्ण रूप से पूरा किया। यदि आप सबसे आधुनिक और सबसे पहले फ़ोनों की तुलना करते हैं, आप तुरंत उन्नीसवीं सदी के अंतिम डिवाइस और आधुनिक स्मार्टफोन के लिए सबसे महत्वपूर्ण कार्यों की पहचान कर सकते हैं। वे कॉल करने की क्षमता और कॉल प्राप्त करने की क्षमता हैं। वास्तव में, यह वही है जो फ़ोन को फ़ोन बनाता है, और कुछ नहीं। अब केवल OOP का एक सिद्धांत लागू किया गया है: किसी वस्तु की सबसे महत्वपूर्ण विशेषताओं और सूचनाओं की पहचान करें। इस सिद्धांत को अमूर्तन कहा जाता है। ओओपी में, अमूर्तता को एक कार्यक्रम में वस्तुओं के रूप में वास्तविक दुनिया के कार्य के तत्वों का प्रतिनिधित्व करने की एक विधि के रूप में भी परिभाषित किया जा सकता है। अमूर्तता हमेशा किसी वस्तु के कुछ गुणों के सामान्यीकरण से जुड़ी होती है, इसलिए मुख्य बात यह है कि हाथ में लिए गए कार्य के संदर्भ में अर्थपूर्ण जानकारी को महत्वहीन से अलग करना है। इसके अतिरिक्त, अमूर्तता के कई स्तर हो सकते हैं। होने देना' आइए अपने फोन पर अमूर्तता के सिद्धांत को लागू करने का प्रयास करें। आरंभ करने के लिए, हम सबसे सामान्य प्रकार के फ़ोनों की पहचान करेंगे — पहले फ़ोन से लेकर आज के फ़ोन तक। उदाहरण के लिए, हम उन्हें चित्र 1 में आरेख के रूप में प्रस्तुत कर सकते हैं। ओओपी के सिद्धांत - 2अमूर्तता का उपयोग करते हुए, अब हम इस वस्तु पदानुक्रम में सामान्य जानकारी की पहचान कर सकते हैं: सामान्य अमूर्त वस्तु (टेलीफोन), टेलीफोन की सामान्य विशेषताएं (उदाहरण के लिए इसके निर्माण का वर्ष), और सामान्य इंटरफ़ेस (सभी टेलीफोन कॉल प्राप्त कर सकते हैं और कॉल कर सकते हैं)। यहाँ यह जावा में कैसा दिखता है:
public abstract class AbstractPhone {
    private int year;

    public AbstractPhone(int year) {
        this.year = year;
    }
    public abstract void call(int outgoingNumber);
    public abstract void ring(int incomingNumber);
}
एक कार्यक्रम में, हम इस सार वर्ग का उपयोग करके और OOP के अन्य बुनियादी सिद्धांतों को लागू करके नए प्रकार के फोन बना सकते हैं, जिन्हें हम नीचे देखेंगे।

कैप्सूलीकरण

अमूर्तता के साथ, हम यह पहचानते हैं कि सभी वस्तुओं के लिए क्या सामान्य है। लेकिन हर तरह का फोन अनोखा होता है, किसी तरह दूसरों से अलग होता है। एक कार्यक्रम में, हम कैसे सीमाएँ बनाते हैं और इस व्यक्तित्व की पहचान करते हैं? हम इसे कैसे बनाते हैं ताकि कोई गलती से या जानबूझकर हमारे फोन को तोड़ न सके या एक मॉडल को दूसरे में बदलने की कोशिश न कर सके? वास्तविक दुनिया में, उत्तर स्पष्ट है: आपको सभी पुर्जों को एक फ़ोन केस में रखना होगा। आखिरकार, यदि आप नहीं करते हैं - इसके बजाय फोन के सभी आंतरिक भागों को छोड़कर बाहर की तरफ तारों को जोड़ते हैं - तो कुछ जिज्ञासु प्रयोगकर्ता निश्चित रूप से हमारे फोन को "सुधार" करना चाहेंगे। इस तरह की छेड़छाड़ को रोकने के लिए, किसी वस्तु के डिजाइन और संचालन में एनकैप्सुलेशन के सिद्धांत का उपयोग किया जाता है। यह सिद्धांत बताता है कि किसी वस्तु के गुण और व्यवहार एक ही वर्ग, वस्तु' में संयुक्त होते हैं। आंतरिक कार्यान्वयन उपयोगकर्ता से छिपा हुआ है, और ऑब्जेक्ट के साथ काम करने के लिए एक सार्वजनिक इंटरफ़ेस प्रदान किया गया है। प्रोग्रामर का कार्य यह निर्धारित करना है कि किसी वस्तु की कौन सी विशेषताएँ और विधियाँ सार्वजनिक पहुँच के लिए उपलब्ध होनी चाहिए, और कौन से आंतरिक कार्यान्वयन विवरण हैं जो दुर्गम होने चाहिए।

Encapsulation और अभिगम नियंत्रण

मान लीजिए कि एक फोन के बारे में जानकारी (उसका उत्पादन वर्ष या निर्माता का लोगो) उसके निर्माण के समय उसके पीछे उकेरा जाता है। सूचना (इसकी स्थिति) इस विशेष मॉडल के लिए विशिष्ट है। हम कह सकते हैं कि निर्माता ने यह सुनिश्चित किया कि यह जानकारी अपरिवर्तनीय थी - यह संभावना नहीं है कि कोई उत्कीर्णन को हटाने के बारे में सोचेगा। जावा दुनिया में, एक वर्ग फ़ील्ड्स का उपयोग करके भविष्य की वस्तुओं की स्थिति का वर्णन करता है, और उनके व्यवहार को विधियों का उपयोग करके वर्णित किया जाता है। किसी वस्तु की स्थिति और व्यवहार तक पहुंच को फ़ील्ड और विधियों पर लागू संशोधक का उपयोग करके नियंत्रित किया जाता है: निजी, संरक्षित, सार्वजनिक और डिफ़ॉल्ट। उदाहरण के लिए, हमने तय किया कि उत्पादन वर्ष, निर्माता का नाम और विधियों में से एक वर्ग के आंतरिक कार्यान्वयन विवरण हैं और कार्यक्रम में अन्य वस्तुओं द्वारा नहीं बदला जा सकता है। कोड में,
public class SomePhone {

    private int year;
    private String company;
    public SomePhone(int year, String company) {
        this.year = year;
        this.company = company;
    }
private void openConnection(){
    // findSwitch
    // openNewConnection...
}
public void call() {
    openConnection();
    System.out.println("Calling");
}

public void ring() {
    System.out.println("Ring-ring");
}

 }
निजी संशोधक वर्ग के क्षेत्रों और विधियों को केवल इस वर्ग के भीतर ही एक्सेस करने की अनुमति देता है। इसका मतलब है कि निजी क्षेत्रों को बाहर से एक्सेस करना असंभव है, क्योंकि निजी तरीकों को नहीं कहा जा सकता है। ओपनकनेक्शन विधि तक पहुंच को प्रतिबंधित करने से हमें विधि के आंतरिक कार्यान्वयन को स्वतंत्र रूप से बदलने की क्षमता भी मिलती है, क्योंकि विधि की गारंटी है कि अन्य वस्तुओं के काम को बाधित या बाधित नहीं किया जाएगा। हमारे ऑब्जेक्ट के साथ काम करने के लिए, हम सार्वजनिक संशोधक का उपयोग करके उपलब्ध कॉल और रिंग विधियों को छोड़ देते हैं। वस्तुओं के साथ काम करने के लिए सार्वजनिक तरीके प्रदान करना भी इनकैप्सुलेशन का हिस्सा है, क्योंकि अगर पहुंच को पूरी तरह से अस्वीकार कर दिया गया, तो यह बेकार हो जाएगा।

विरासत

आइए फोन के आरेख पर एक और नज़र डालें। आप देख सकते हैं कि यह एक पदानुक्रम है जिसमें एक मॉडल में अपनी शाखा के साथ उच्चतर स्थित मॉडल की सभी विशेषताएं होती हैं, और कुछ स्वयं जोड़ती हैं। उदाहरण के लिए, एक स्मार्टफोन संचार के लिए एक सेलुलर नेटवर्क का उपयोग करता है (इसमें एक सेल फोन के गुण होते हैं), वायरलेस और पोर्टेबल (एक ताररहित फोन के गुण होते हैं), और कॉल प्राप्त कर सकते हैं और कॉल कर सकते हैं (फोन के गुण हैं)। हमारे पास यहां वस्तु गुणों की विरासत है। प्रोग्रामिंग में, वंशानुक्रम का अर्थ है नए वर्गों को परिभाषित करने के लिए मौजूदा वर्गों का उपयोग करना। आइए स्मार्टफोन क्लास बनाने के लिए इनहेरिटेंस का उपयोग करने के एक उदाहरण पर विचार करें। सभी ताररहित फोन रिचार्जेबल बैटरी द्वारा संचालित होते हैं, जिनमें एक निश्चित बैटरी जीवन होता है। तदनुसार, हम इस संपत्ति को ताररहित फोन वर्ग में जोड़ते हैं:
public abstract class CordlessPhone extends AbstractPhone {

    private int hour;

    public CordlessPhone (int year, int hour) {
        super(year);
        this.hour = hour;
    }
    }
सेल फोन एक ताररहित फोन के गुणों को प्राप्त करते हैं, और हम इस वर्ग में कॉल और रिंग विधियों को लागू करते हैं:
public class CellPhone extends CordlessPhone {
    public CellPhone(int year, int hour) {
        super(year, hour);
    }

    @Override
    public void call(int outgoingNumber) {
        System.out.println("Calling " + outgoingNumber);
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("Incoming call from " + incomingNumber);
    }
}
और अंत में, हमारे पास स्मार्टफोन वर्ग है, जिसमें क्लासिक सेल फोन के विपरीत एक पूर्ण ऑपरेटिंग सिस्टम है। आप नए प्रोग्राम जोड़कर अपने स्मार्टफोन की कार्यक्षमता बढ़ा सकते हैं जो इसके ऑपरेटिंग सिस्टम पर चल सकते हैं। कोड में, वर्ग को निम्नानुसार वर्णित किया जा सकता है:
public class Smartphone extends CellPhone {

    private String operationSystem;

    public Smartphone(int year, int hour, String operationSystem) {
        super(year, hour);
        this.operationSystem = operationSystem;
    }
public void install(String program) {
    System.out.println("Installing " + program + " for " + operationSystem);
}

}
जैसा कि आप देख सकते हैं, हमने स्मार्टफ़ोन वर्ग का वर्णन करने के लिए काफी नया कोड बनाया है , लेकिन हमें नई कार्यक्षमता के साथ एक नया वर्ग मिला है। ओओपी का यह सिद्धांत आवश्यक जावा कोड की मात्रा को काफी कम करना संभव बनाता है, जिससे प्रोग्रामर के लिए जीवन आसान हो जाता है।

बहुरूपता

विभिन्न प्रकार के फ़ोनों के स्वरूप और डिज़ाइन में अंतर होने के बावजूद, हम कुछ सामान्य व्यवहार की पहचान कर सकते हैं: वे सभी कॉल प्राप्त कर सकते हैं और कॉल कर सकते हैं और सभी के पास नियंत्रण का एक स्पष्ट और सरल सेट होता है। प्रोग्रामिंग के संदर्भ में, अमूर्तता का सिद्धांत (जिससे हम पहले से ही परिचित हैं) हमें यह कहने देता है कि फ़ोन ऑब्जेक्ट्स का एक सामान्य इंटरफ़ेस है। यही कारण है कि लोग डिवाइस के तकनीकी विवरण में जाने के बिना, समान नियंत्रण (यांत्रिक बटन या टचस्क्रीन) वाले फोन के विभिन्न मॉडलों का आसानी से उपयोग कर सकते हैं। इस प्रकार, आप लगातार एक सेल फोन का उपयोग करते हैं और आप अपने मित्र के लैंडलाइन से आसानी से कॉल कर सकते हैं। ओओपी का सिद्धांत जो कहता है कि एक प्रोग्राम वस्तु की आंतरिक संरचना के बारे में किसी भी जानकारी के बिना एक सामान्य इंटरफ़ेस के साथ वस्तुओं का उपयोग कर सकता है, बहुरूपता कहलाता है। होने देना' आइए कल्पना करें कि हमें एक उपयोगकर्ता का वर्णन करने के लिए हमारे कार्यक्रम की आवश्यकता है जो किसी अन्य उपयोगकर्ता को कॉल करने के लिए किसी भी फोन का उपयोग कर सकता है। यहां बताया गया है कि हम इसे कैसे कर सकते हैं:
public class User {
    private String name;

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

    public void callAnotherUser(int number, AbstractPhone phone){
// And here's polymorphism: using the AbstractPhone type in the code!
        phone.call(number);
    }
}
 }
अब हम कई प्रकार के फ़ोनों का वर्णन करेंगे। पहले फोन में से एक:
public class ThomasEdisonPhone extends AbstractPhone {

public ThomasEdisonPhone(int year) {
    super(year);
}
    @Override
    public void call(int outgoingNumber) {
        System.out.println("Crank the handle");
        System.out.println("What number would you like to connect to?");
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("The phone is ringing");
    }
}
एक साधारण लैंडलाइन फोन:
public class Phone extends AbstractPhone {

    public Phone(int year) {
        super(year);
    }

    @Override
    public void call(int outgoingNumber) {
        System.out.println("Calling " + outgoingNumber);
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("The phone is ringing");
    }
}
और अंत में, एक अच्छा वीडियो फोन:
public class VideoPhone extends AbstractPhone {

    public VideoPhone(int year) {
        super(year);
    }
    @Override
    public void call(int outgoingNumber) {
        System.out.println("Connecting video call to " + outgoingNumber);
    }
    @Override
    public void ring(int incomingNumber) {
        System.out.println("Incoming video call from " + incomingNumber);
    }
  }
हम main() मेथड में ऑब्जेक्ट बनाएंगे और callAnotherUser() मेथड का परीक्षण करेंगे:
AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
AbstractPhone phone = new Phone(1984);
AbstractPhone videoPhone=new VideoPhone(2018);
User user = new User("Jason");
user.callAnotherUser(224466, firstPhone);
// Crank the handle
// What number would you like to connect to?
user.callAnotherUser(224466, phone);
// Calling 224466
user.callAnotherUser(224466, videoPhone);
// Connecting video call to 224466
उपयोगकर्ता ऑब्जेक्ट पर एक ही विधि को कॉल करने से अलग-अलग परिणाम उत्पन्न होते हैं। कॉल विधि का एक विशिष्ट कार्यान्वयन गतिशील रूप से कॉलअनदरयूज़र () विधि के अंदर चुना जाता है, जो प्रोग्राम के चलने पर पारित विशिष्ट प्रकार की वस्तु के आधार पर होता है। यह बहुरूपता का मुख्य लाभ है - रनटाइम पर कार्यान्वयन को चुनने की क्षमता। ऊपर दिए गए फोन क्लास के उदाहरणों में, हमने मेथड ओवरराइडिंग का इस्तेमाल किया - एक ट्रिक जहां हम मेथड सिग्नेचर को बदले बिना बेस क्लास में परिभाषित एक मेथड के इम्प्लीमेंटेशन को बदलते हैं। यह अनिवार्य रूप से विधि को प्रतिस्थापित करता है: उपवर्ग में परिभाषित नई विधि को प्रोग्राम निष्पादित होने पर कहा जाता है। आमतौर पर, जब हम किसी विधि को ओवरराइड करते हैं, तो @Overrideएनोटेशन का उपयोग किया जाता है। यह संकलक को ओवरराइड और ओवरराइडिंग विधियों के हस्ताक्षरों की जांच करने के लिए कहता है। अंत में, यह सुनिश्चित करने के लिए कि आपके जावा प्रोग्राम OOP के सिद्धांतों के अनुरूप हैं, इन युक्तियों का पालन करें:
  • किसी वस्तु की मुख्य विशेषताओं की पहचान करें;
  • कक्षाएं बनाते समय सामान्य गुणों और व्यवहार की पहचान करें और वंशानुक्रम का उपयोग करें;
  • वस्तुओं का वर्णन करने के लिए सार प्रकारों का उपयोग करें;
  • कक्षा के आंतरिक कार्यान्वयन से संबंधित विधियों और क्षेत्रों को हमेशा छिपाने का प्रयास करें।
टिप्पणियां
  • लोकप्रिय
  • नया
  • पुराना
टिप्पणी लिखने के लिए आपको साइन इन करना होगा
इस पेज पर अभी तक कोई टिप्पणियां नहीं हैं