हम जावा में बच्चे के ऑब्जेक्ट के लिए एक मूल संदर्भ क्यों निर्दिष्ट करते हैं?


84

मैं एक बहुत ही सरल प्रश्न पूछ रहा हूं, लेकिन मैं इसमें थोड़ा भ्रमित हूं।

मान लीजिए कि मेरे पास एक वर्ग है Parent:

public class Parent {

    int name;
}

और एक और वर्ग है Child:

public class Child extends Parent{

    int salary;
}

और अंत में मेरा Main.java वर्ग

public class Main {

    public static void main(String[] args)
    {
        Parent parent = new Child();
        parent.name= "abcd";
    }
}

अगर मैं एक बच्चे की तरह वस्तु

Child child = new Child():

फिर childऑब्जेक्ट दोनों name and salaryचर को एक्सेस कर सकता है।

मेरा सवाल यह है कि:

Parent parent = new Child();

nameअभिभावक वर्ग के केवल चर की पहुँच देता है । तो इस लाइन का सटीक उपयोग क्या है ??

 Parent parent = new Child();

और यह भी जब यह गतिशील बहुरूपता का उपयोग कर रहा है तो ऐसा करने के बाद बाल वर्ग का चर सुलभ क्यों नहीं है

Parent parent = new Child();

1
जानवरों के उदाहरण के बारे में यहाँ पढ़ें: en.wikipedia.org/wiki/…
mrswadge

आपके उदाहरण में यह वास्तव में मदद नहीं करता है। लेकिन सोचें कि आपके पास एक ऐसी विधि है जो किसी जनक संदर्भ के साथ कुछ करती है। उदाहरण के लिए, मुख्य वर्ग में कहीं। यह एक मूल वस्तु संदर्भ लेता है और इसके साथ सामान करता है। इसका अर्थ यह भी होगा कि वह माता-पिता की उप-कक्षाओं को भी एक बाल वस्तु की तरह स्वीकार कर ले, भले ही यह केवल माता-पिता के लिए ही हो। इसके अलावा, अधिक दिलचस्प सामान के लिए गतिशील बंधन में देखें
आंद्रेई बोर्सन

क्या यह nameसही प्रकार है?
रोमन सी

जवाबों:


53

सबसे पहले, शब्दावली का स्पष्टीकरण: हम एक Childऑब्जेक्ट को एक प्रकार के चर में असाइन कर रहे हैं ParentParentएक वस्तु का एक संदर्भ है, जो एक उप-प्रकार होने के लिए होता है Parent, ए Child

यह केवल अधिक जटिल उदाहरण में उपयोगी है। कल्पना कीजिए कि आप getEmployeeDetailsकक्षा में शामिल होते हैं:

public String getEmployeeDetails() {
    return "Name: " + name;
}

हम Childअधिक जानकारी प्रदान करने के लिए उस पद्धति को ओवरराइड कर सकते हैं :

@Override
public String getEmployeeDetails() {
    return "Name: " + name + " Salary: " + salary;
}

अब आप कोड की एक पंक्ति लिख सकते हैं, जो भी विवरण उपलब्ध है, चाहे वह वस्तु एक हो Parentया Child:

parent.getEmployeeDetails();

निम्नलिखित कोड:

Parent parent = new Parent();
parent.name = 1;
Child child = new Child();
child.name = 2;
child.salary = 2000;
Parent[] employees = new Parent[] { parent, child };
for (Parent employee : employees) {
    employee.getEmployeeDetails();
}

उत्पादन में परिणाम होगा:

Name: 1
Name: 2 Salary: 2000

हम एक के Childरूप में इस्तेमाल किया Parent। इसने Childकक्षा के लिए विशिष्ट व्यवहार किया था , लेकिन जब हमने कॉल किया getEmployeeDetails()तो हम अंतर को अनदेखा कर सकते थे और ध्यान केंद्रित कर सकते थे कि कैसे Parentऔर Childसमान हैं। इसे उपप्रकार बहुरूपता कहा जाता है

आपका अद्यतन प्रश्न पूछता है कि Child.salaryजब Childऑब्जेक्ट किसी Parentसंदर्भ में संग्रहीत किया गया है , तो पहुंच क्यों नहीं है । उत्तर "बहुरूपता" और "स्थैतिक टाइपिंग" का प्रतिच्छेदन है। क्योंकि जावा संकलित समय पर सांख्यिकीय रूप से टाइप किया जाता है, इसलिए आपको संकलक से कुछ गारंटी मिलती है, लेकिन आपको बदले में नियमों का पालन करने के लिए मजबूर किया जाता है या कोड संकलित नहीं होगा। यहाँ, प्रासंगिक गारंटी यह है कि एक उपप्रकार (जैसे Child) के प्रत्येक उदाहरण का उपयोग इसके सुपरपेप्ट (उदाहरण Parent) के उदाहरण के रूप में किया जा सकता है । उदाहरण के लिए, आपको गारंटी दी जाती है कि जब आप पहुँचते हैं employee.getEmployeeDetailsया employee.nameविधि या क्षेत्र को किसी गैर-अशक्त वस्तु पर परिभाषित किया जाता है जिसे किसी employeeप्रकार के चर के लिए सौंपा जा सकता हैParent। यह गारंटी देने के लिए, कंपाइलर केवल उस स्थिर प्रकार (मूल रूप से, चर संदर्भ का प्रकार Parent) पर विचार करता है , जब आप यह तय कर सकते हैं कि आप क्या एक्सेस कर सकते हैं। तो अगर आप किसी भी सदस्य उस वस्तु की क्रम प्रकार पर परिभाषित कर रहे हैं उपयोग नहीं कर सकते, Child

जब आप वास्तव में एक के Childरूप में उपयोग करना चाहते हैं तो Parentयह एक आसान प्रतिबंध है और आपका कोड Parentइसके सभी उपप्रकारों के लिए उपयोग करने योग्य होगा । जब यह स्वीकार्य नहीं है, तो संदर्भ का प्रकार बनाएं Child


22

जब आप अपने कार्यक्रम को संकलित करते हैं तो बेस क्लास का संदर्भ चर स्मृति प्राप्त करता है और कंपाइलर उस कक्षा के सभी तरीकों की जांच करता है। इसलिए यह सभी बेस क्लास विधियों की जाँच करता है लेकिन चाइल्ड क्लास विधियों की नहीं। अब रनटाइम में जब ऑब्जेक्ट बनाया जाता है, तो केवल चेक किए गए तरीके ही चल सकते हैं। मामले में एक विधि बच्चे के वर्ग में ओवरराइड होती है जो कार्य करती है। बाल वर्ग के अन्य कार्य नहीं चल रहे हैं क्योंकि संकलक ने उन्हें संकलन समय पर मान्यता नहीं दी है।


1
यह उत्तर समझ में आता है! धन्यवाद
user7098526

13

यह आपको एक आम अभिभावक इंटरफ़ेस के माध्यम से सभी उपवर्गों तक पहुँचने की अनुमति देता है। यह सभी उपवर्गों पर उपलब्ध सामान्य परिचालन चलाने के लिए फायदेमंद है। एक बेहतर उदाहरण की आवश्यकता है:

public class Shape
{
  private int x, y;
  public void draw();
}

public class Rectangle extends Shape
{ 
  public void draw();
  public void doRectangleAction();
}

अब अगर आपके पास:

List<Shape> myShapes = new ArrayList<Shape>();

आप सूची में प्रत्येक आइटम को एक आकृति के रूप में संदर्भित कर सकते हैं, यदि आपको एक आयत या कुछ अन्य प्रकार की चिंता नहीं करनी है जैसे कि सर्किल कहें। आप उन सभी के साथ एक जैसा व्यवहार कर सकते हैं; आप उन सभी को आकर्षित कर सकते हैं। आप doRectangleAction को कॉल नहीं कर सकते क्योंकि आपको पता नहीं है कि क्या आकार वास्तव में एक आयत है।

यह एक सामान्य फैशन में वस्तुओं का इलाज करने और विशेष रूप से इलाज करने के बीच आप का एक व्यापार है।

वास्तव में मुझे लगता है कि आपको OOP के बारे में अधिक पढ़ने की आवश्यकता है। एक अच्छी पुस्तक में मदद करनी चाहिए: http://www.amazon.com/Design-Patterns-Explained-Perspective-Object-Oriented/dp/0201715945


2
आपके उदाहरण में उद्धृत, क्या आप "अमूर्त वर्ग" या "इंटरफ़ेस" का उपयोग कर रहे हैं? क्योंकि एक साधारण वर्ग के पास अनुपयोगी तरीके नहीं हो सकते।
मुख्यालय 31

1
@HQuser - अच्छी तरह से देखा जाता है, ऐसा लगता है कि प्रश्न के संदर्भ में बहुरूपता पर अधिक व्याख्या करना चाहता है, लेकिन निश्चित रूप से यह आवश्यकता है।
विवेक

11

यदि आप मूल प्रकार को उपवर्ग में निर्दिष्ट करते हैं तो इसका अर्थ है कि आप मूल वर्ग की सामान्य विशेषताओं का उपयोग करने के लिए सहमत हैं।

यह आपको विभिन्न उपवर्ग कार्यान्वयन से अमूर्त करने की स्वतंत्रता देता है। परिणामस्वरूप आप मूल सुविधाओं के साथ सीमित हो जाते हैं।

हालांकि, इस प्रकार के असाइनमेंट को अपकास्टिंग कहा जाता है।

Parent parent = new Child();  

इसके विपरीत है डाउनकास्टिंग।

Child child = (Child)parent;

इसलिए, यदि आप इसका उदाहरण बनाते हैं Childऔर इसे नीचे करते Parentहैं , तो आप उस प्रकार की विशेषता का उपयोग कर सकते हैं name। यदि आप इसका उदाहरण बनाते Parentहैं तो पिछले मामले के समान ही कर सकते हैं, लेकिन आप इसका उपयोग नहीं कर सकते salaryक्योंकि इसमें ऐसी विशेषता नहीं है Parent। पिछले मामले पर लौटें जो उपयोग कर सकते हैं salaryलेकिन केवल अगर डाउनकास्टिंग करने के लिए Child

अधिक विवरण व्याख्या है


तो इसके लिए मैं पेरेंट पेरेंट = न्यू पेरेंट () कर सकता हूं। वह क्यों करें? Plz मेरी मदद करो।
नरेंद्र पाल

सच है, लेकिन फिर भी यह नहीं समझाता कि आप क्यों करना चाहते हैं।
जॉन वाट्स

क्यों करना है यह इस पर निर्भर करता है कि आप क्या करना चाहते हैं।
रोमन सी

यदि आप असाइन Parentकरते हैं Parentतो आप उपयोग कर सकते हैं यदि आप असाइन करते हैं (यदि आप कर सकते हैं) Childतो आप उपयोग कर सकते हैं Child
रोमन सी

1
बच्चा बच्चा = (बाल) माता-पिता; यह ClassCastException में परिणाम देगा। आप चाइल्ड रेफरेंस वेरिएबल में पैरेंट ऑब्जेक्ट को डाउनकास्ट नहीं कर सकते।
मुहम्मद सलमान फारूक

7

यह आसान है।

Parent parent = new Child();

इस स्थिति में ऑब्जेक्ट का प्रकार है Parent। चींटी Parentमें केवल एक गुण होता है। यह है name

Child child = new Child();

और इस मामले में वस्तु का प्रकार है Child। चींटी Childके दो गुण होते हैं। वे nameऔर salary

तथ्य यह है कि घोषणा पर तुरंत गैर-अंतिम फ़ील्ड को प्रारंभ करने की कोई आवश्यकता नहीं है। आमतौर पर यह रन-टाइम पर किया जाता है क्योंकि अक्सर आप यह नहीं जान सकते कि वास्तव में आपको किस कार्यान्वयन की आवश्यकता होगी। उदाहरण के लिए कल्पना करें कि आपके पास Transportसिर पर वर्ग के साथ एक श्रेणी पदानुक्रम है । और तीन उपवर्गों: Car, Helicopterऔर Boat। और एक और वर्ग है Tourजिसमें फ़ील्ड है Transport। अर्थात्:

class Tour {
   Transport transport;
}  

जब तक एक उपयोगकर्ता ने एक यात्रा बुक नहीं की है और एक विशेष प्रकार का परिवहन नहीं चुना है, तो आप इस क्षेत्र को आरंभ नहीं कर सकते। यह पहले है।

दूसरा, मान लें कि इन सभी वर्गों के पास एक विधि होनी चाहिए go()लेकिन एक अलग कार्यान्वयन के साथ। आप सुपरक्लास में डिफ़ॉल्ट रूप से एक बुनियादी कार्यान्वयन Transportऔर प्रत्येक उपवर्ग में अद्वितीय कार्यान्वयन को परिभाषित कर सकते हैं । इस आरंभीकरण के साथ Transport tran; tran = new Car();आप विधि को कॉल कर सकते हैं tran.go()और विशिष्ट कार्यान्वयन के बारे में चिंता किए बिना परिणाम प्राप्त कर सकते हैं । यह विशेष उपवर्ग से अतिरंजित विधि को बुलाएगा।

इसके अलावा आप हर जगह सबक्लास के उदाहरण का उपयोग कर सकते हैं जहां सुपरक्लास का उपयोग किया जाता है। उदाहरण के लिए आप अपने परिवहन को किराए पर देने का अवसर प्रदान करना चाहते हैं। : यदि आप बहुरूपता का उपयोग नहीं करते हैं, तो आप प्रत्येक मामले के लिए तरीकों की एक बहुत कुछ लिखने के लिए है rentCar(Car car), rentBoat(Boat boat)इसके आगे और। उसी समय बहुरूपता आपको एक सार्वभौमिक विधि बनाने की अनुमति देता है rent(Transport transport)। आप इसमें किसी भी उपवर्ग के ऑब्जेक्ट को पास कर सकते हैं Transport। इसके अलावा, अगर समय के साथ आपका तर्क बढ़ेगा और आपको पदानुक्रम में एक और वर्ग बनाने की आवश्यकता होगी? बहुरूपता का उपयोग करते समय आपको कुछ भी बदलने की आवश्यकता नहीं होती है। बस कक्षा का विस्तार करें Transportऔर अपनी नई कक्षा को विधि में पास करें:

public class Airplane extends Transport {
    //implementation
}

और rent(new Airplane())। और new Airplane().go()दूसरे मामले में।


मुझे पता है, लेकिन मेरा सवाल यह है कि ऐसा क्यों करना है? अगर हम पेरेंट रेफरेंस पाने के लिए पेरेंट पी = न्यू पेरेंट () कर सकते हैं।
नरेन्द्र पाल

यह बहुरूपता है । बहुत काम का है। बहुरूपता आपके कार्यक्रम को अधिक लचीला और एक्स्टेंसिबल बनाता है। यह वास्तव में कितना उपयोगी हो सकता है? अद्यतन उत्तर में मेरे उदाहरण देखें ।
कपेलचिक २ Kap

1
परिवहन के साथ महान उदाहरण ... आसानी से समझ में आया। धन्यवाद!
चनवो पार्क

2

यह स्थिति तब होती है जब आपके पास कई कार्यान्वयन होते हैं। मुझे समझाने दो। मान लें कि आपके पास कई सॉर्टिंग एल्गोरिथ्म हैं और आप रनटाइम को चुनना चाहते हैं जिसे लागू करने के लिए, या आप किसी और को उसके कार्यान्वयन को जोड़ने की क्षमता देना चाहते हैं। इस समस्या को हल करने के लिए आप आमतौर पर एक अमूर्त वर्ग (पैरेंट) बनाते हैं और अलग-अलग कार्यान्वयन (चाइल्ड) करते हैं। यदि आप लिखते हैं:

Child c = new Child();

आप अपने कार्यान्वयन को चाइल्ड क्लास से जोड़ते हैं और आप इसे अब और नहीं बदल सकते। अन्यथा यदि आप उपयोग करते हैं:

Parent p = new Child();

जब तक चाइल्ड पेरेंट का विस्तार करता है, आप भविष्य में इसे कोड को संशोधित किए बिना बदल सकते हैं।

इंटरफेस का उपयोग करके एक ही काम किया जा सकता है: माता-पिता अब क्लास नहीं बल्कि जावा इंटरफेस है।

सामान्य तौर पर आप डीएओ पैटर्न में इस एप्रोच का उपयोग कर सकते हैं जहां आप कई डीबी पर निर्भर कार्यान्वयन चाहते हैं। आप FactoryPatter या AbstractFactory पैटर्न पर एक नज़र दे सकते हैं। आशा है इससे आपको सहायता मिलेगी।


1

मान लीजिए कि आप पैरेंट क्लास के उदाहरणों की एक सरणी रखना चाहते हैं, और चाइल्ड 1, चाइल्ड 2, चाइल्ड 3 के अभिभावकों के बच्चे का एक सेट। ऐसी स्थितियाँ हैं जब आप केवल अभिभावक वर्ग के कार्यान्वयन में रुचि रखते हैं, जो अधिक सामान्य है, और बाल वर्गों द्वारा शुरू किए गए अधिक विशिष्ट सामानों की परवाह नहीं करते हैं।


1

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

  1. तत्काल कारण जटिलता को छिपाना है, ताकि कॉल करने वाले को अक्सर बदलने की आवश्यकता न हो (आम आदमी की शर्तों में हैक और जैक हो)। यह बहुत मायने रखता है, खासकर यदि आप लक्ष्य बनाते हैं कि कीड़े पैदा करने से बचें। और जितना अधिक आप कोड को संशोधित करते हैं, उतनी अधिक संभावना है कि आप उनमें से कुछ को अपने ऊपर रेंगेंगे। दूसरी ओर, यदि आप कोड को बढ़ाते हैं, तो यह कम संभावना है कि आपके पास कीड़े होंगे क्योंकि आप एक समय में एक चीज पर ध्यान केंद्रित करते हैं और आपका पुराना कोड सिर्फ थोड़ा सा बदलता या बदलता नहीं है। कल्पना करें कि आपके पास सरल अनुप्रयोग है जो कर्मचारियों को चिकित्सा पेशे में प्रोफाइल बनाने की अनुमति देता है। सादगी के लिए, मान लें कि हमारे पास केवल जनरलप्रैक्टिशनर्स, सर्जन और नर्स हैं (वास्तव में कई और विशिष्ट पेशे हैं, निश्चित रूप से)। प्रत्येक पेशे के लिए, आप कुछ सामान्य जानकारी और अकेले उस पेशेवर के लिए कुछ विशिष्ट स्टोर करना चाहते हैं। उदाहरण के लिए, एक सर्जन के पास सामान्य क्षेत्र हो सकते हैं जैसे फर्स्टनाम, लास्टनाम, इयरऑफ एक्सपीरियंस जनरल फील्ड्स, लेकिन विशिष्ट फील्ड्स, जैसे लिस्ट इंस्टेंस में संग्रहित स्पेशलाइजेशन, जैसे लिस्ट के साथ कंटेंट सिमर के साथ "बोन सर्जरी", "आई सर्जरी", आदि। एक नर्स के पास इनमें से कोई भी नहीं होगा, लेकिन सूची प्रक्रिया हो सकती है जिससे वे परिचित हैं, जनरलप्रेनर की अपनी स्वयं की बारीकियां होंगी। नतीजतन, आप एक विशेष की प्रोफ़ाइल को कैसे सहेजते हैं। हालाँकि, आप नहीं चाहते हैं कि आपका ProfileManager वर्ग इन अंतरों के बारे में जाने, क्योंकि वे समय के साथ अनिवार्य रूप से बदलेंगे और बढ़ेंगे क्योंकि आपका आवेदन अधिक चिकित्सीय व्यवसायों, जैसे फिजियो थेरेपिस्ट, कार्डियोलॉजिस्ट, ऑन्कोलॉजिस्ट आदि को कवर करने के लिए अपनी कार्यक्षमता बढ़ाता है। आप बस इतना करना चाहते हैं कि आपका ProfileManger कह रहा है कि सेव करें (), कोई फर्क नहीं पड़ता कि यह किसका प्रोफाइल सेव कर रहा है। इस प्रकार, यह पीछे और इंटरफ़ेस, और एब्सट्रैक्ट क्लास, या एक पैरेंट क्लास (यदि आप एक सामान्य चिकित्सा बनाने की अनुमति देने की योजना बनाते हैं) को छिपाने के लिए सामान्य अभ्यास है। इस मामले में, एक अभिभावक वर्ग चुनें और उसे मेडिकलइम्प्लॉई कहें। कवर के तहत, यह ऊपर दी गई विशिष्ट कक्षाओं में से किसी को भी संदर्भित कर सकता है। जब ProfileManager ने myMedicalEmployee.save () सहेजें () विधि को पॉलीमॉर्फिक (कई-संरचनात्मक रूप से) सही वर्ग प्रकार को हल किया जाएगा जो मूल रूप से प्रोफ़ाइल बनाने के लिए उपयोग किया गया था, नर्स के लिए और उस में सहेजें () विधि को कॉल करें कक्षा। या एक अभिभावक वर्ग (यदि आप एक सामान्य चिकित्सा कर्मचारी बनाने की अनुमति देने की योजना बनाते हैं)। इस मामले में, एक अभिभावक वर्ग चुनें और उसे मेडिकलइम्प्लॉई कहें। कवर के तहत, यह ऊपर दी गई विशिष्ट कक्षाओं में से किसी को भी संदर्भित कर सकता है। जब ProfileManager ने myMedicalEmployee.save () सहेजें () विधि को पॉलीमॉर्फिक (कई-संरचनात्मक रूप से) सही वर्ग प्रकार को हल किया जाएगा जो मूल रूप से प्रोफ़ाइल बनाने के लिए उपयोग किया गया था, नर्स के लिए और उस में सहेजें () विधि को कॉल करें कक्षा। या एक अभिभावक वर्ग (यदि आप एक सामान्य चिकित्सा कर्मचारी बनाने की अनुमति देने की योजना बनाते हैं)। इस मामले में, एक अभिभावक वर्ग चुनें और उसे मेडिकलइम्प्लॉई कहें। कवर के तहत, यह ऊपर दी गई विशिष्ट कक्षाओं में से किसी को भी संदर्भित कर सकता है। जब ProfileManager ने myMedicalEmployee.save () सहेजें () विधि को पॉलीमॉर्फिक (कई-संरचनात्मक रूप से) सही वर्ग प्रकार को हल किया जाएगा जो मूल रूप से प्रोफ़ाइल बनाने के लिए उपयोग किया गया था, नर्स के लिए और उस में सहेजें () विधि को कॉल करें कक्षा।

  2. कई मामलों में, आप वास्तव में नहीं जानते हैं कि रनटाइम में आपको किस कार्यान्वयन की आवश्यकता होगी। ऊपर दिए गए उदाहरण से, आपको पता नहीं है कि क्या एक GeneralPractitioner, एक सर्जन या एक नर्स एक प्रोफ़ाइल बनाएगा। फिर भी, आप जानते हैं कि एक बार पूरा होने के बाद आपको उस प्रोफ़ाइल को सहेजना होगा, चाहे जो भी हो। MedicalEmployee.profile () ठीक यही करता है। यह प्रत्येक विशिष्ट प्रकार के मेडिकल इम्प्लॉई द्वारा प्रतिरूपित (ओवरराइड) किया जाता है - जनरलप्रैक्टिशनर, सर्जन, नर्सरी,

  3. ऊपर (1) और (2) का परिणाम यह है कि अब आप नए मेडिकल प्रोफेशन को जोड़ सकते हैं, प्रत्येक नई कक्षा में सेव () को लागू कर सकते हैं, जिससे मेडिकलइम्प्लॉई में सेव () विधि को ओवरराइड कर सकते हैं, और आपको ProfileManager को संशोधित नहीं करना पड़ेगा सब।


1

मुझे पता है कि यह एक बहुत पुराना धागा है लेकिन मैं एक ही संदेह में आया था।

तो इस अवधारणा का Parent parent = new Child();जावा में जल्दी और देर से बंधन के साथ कुछ करना है।

निजी, स्थिर और अंतिम तरीकों का बंधन संकलन पर होता है क्योंकि उन्हें ओवरराइड नहीं किया जा सकता है और सामान्य विधि कॉल और अतिभारित विधियाँ प्रारंभिक बंधन का उदाहरण हैं।

उदाहरण पर विचार करें:

class Vehicle
{
    int value = 100;
    void start() {
        System.out.println("Vehicle Started");
    }

    static void stop() {
        System.out.println("Vehicle Stopped");
    }
}

class Car extends Vehicle {

    int value = 1000;

    @Override
    void start() {
        System.out.println("Car Started");
    }

    static void stop() {
        System.out.println("Car Stopped");
    }

    public static void main(String args[]) {

        // Car extends Vehicle
        Vehicle vehicle = new Car();
        System.out.println(vehicle.value);
        vehicle.start();
        vehicle.stop();
    }
}

आउटपुट: 100

कार स्टार्ट हुई

वाहन रोक दिया

ऐसा इसलिए हो रहा है क्योंकि stop()यह एक स्थिर विधि है और इसे ओवरराइड नहीं किया जा सकता है। इसलिए stop()संकलन समय पर होता है और start()यह गैर-स्थैतिक होता है और इसे बाल वर्ग में ओवरराइड किया जाता है। तो, प्रकार के ऑब्जेक्ट के बारे में जानकारी केवल रन टाइम (देर से बाध्यकारी) पर उपलब्ध है और इसलिए start()कार क्लास की विधि को कहा जाता है।

इस कोड में भी vehicle.valueहमें 100आउटपुट के रूप में दिया गया है क्योंकि वेरिएबल इनिशियलाइज़ेशन लेट बाइंडिंग के अंतर्गत नहीं आता है। ओवरराइड करने का तरीका एक तरीका है जिसमें जावा रन टाइम पॉलिमोर्फिज्म का समर्थन करता है

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

मुझे उम्मीद है कि यह उत्तर Parent parent = new Child();महत्वपूर्ण है और यह भी कि आप उपरोक्त संदर्भ का उपयोग करके बाल वर्ग चर का उपयोग क्यों नहीं कर पाए।


-1

उदाहरण के लिए हमने ए

class Employee

{

int getsalary()

{return 0;}

String getDesignation()

{

returndefault”;

}

}

class Manager extends Employee

{

int getsalary()

{

return 20000;

}

String getDesignation()

{

return “Manager”

}

}

class SoftwareEngineer extends Employee

{

int getsalary()

{

return 20000;

}

String getDesignation()

{

return “Manager”

}

}

अब यदि आप सभी कर्मचारियों का वेतन और पदनाम निर्धारित करना चाहते हैं (जैसे कि सॉफ्टवेयर एनीनेरे, मैनेजर आदि)

हम एंप्लॉयी की एक सरणी लेंगे और दोनों तरीके को गेटेलरी (), गेटडिजेशन कहेंगे

Employee arr[]=new Employee[10];

arr[1]=new SoftwareEngieneer();

arr[2]=new Manager();

arr[n]=…….

for(int i;i>arr.length;i++)

{

System.out.println(arr[i].getDesignation+””+arr[i].getSalary())

}

अब इसकी एक प्रकार की ढीली कपलिंग है क्योंकि आपके पास विभिन्न प्रकार के कर्मचारी हो सकते हैं: सॉफ्टवेअर इंजीनियर, प्रबंधक, एचआर, पेंट्रीएम्पलाईजर आदि।

इसलिए आप अलग-अलग कर्मचारी ऑब्जेक्ट के बावजूद मूल संदर्भ के लिए ऑब्जेक्ट दे सकते हैं


-3

आप माता-पिता को माता-पिता घोषित करते हैं, इसलिए जावा माता-पिता वर्ग की केवल विधियाँ और विशेषताएँ प्रदान करेगा।

Child child = new Child();

कार्य करना चाहिए। या

Parent child = new Child();
((Child)child).salary = 1;

1
बेशक यह काम करता है। ओपी एक संदर्भ के लिए पूछ रहा था, जहां Parent parent = new Child();उपयोगी / सार्थक है।
बाज़

2
इसकी व्याख्या अन्य उत्तरों की तरह ही है, इसलिए इसे क्यों घटाया जाए? मैं नहीं कहता कि मैं काम नहीं कर रहा हूँ, मैं कहता हूँ अगर आप कहते हैं कि चाइल्ड c = नया परेंट () आपके पास माता-पिता का उदाहरण है और चाइल्ड का नहीं है, और इसलिए आपके पास कोई विशेषता वेतन नहीं है। अगर आप एट्रीब्यूशन सैलरी चाहते हैं तो आपको चाइल्ड या कास्ट पेरेंट टू चाइल्ड बनाने की जरूरत है ....
थारगू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.