क्या हम एक अमूर्त वर्ग को तात्कालिक कर सकते हैं?


573

मेरे एक साक्षात्कार के दौरान, मुझसे पूछा गया था कि "क्या हम एक अमूर्त वर्ग को त्वरित कर सकते हैं?"

मेरा जवाब था "नहीं, हम नहीं कर सकते"। लेकिन, साक्षात्कारकर्ता ने मुझे कहा "गलत, हम कर सकते हैं।"

मैंने इस पर थोड़ा तर्क दिया। फिर उसने मुझसे कहा कि मैं खुद घर पर यह कोशिश करूँ।

abstract class my {
    public void mymethod() {
        System.out.print("Abstract");
    }
}

class poly {
    public static void main(String a[]) {
        my m = new my() {};
        m.mymethod();
    }
}

यहाँ, मैं अपनी कक्षा और अमूर्त वर्ग की कॉलिंग विधि का उदाहरण बना रहा हूँ। क्या कोई मुझे यह समझा सकता है? क्या मैं अपने साक्षात्कार के दौरान वास्तव में गलत था?


2
हालांकि केवल थोड़ा संबंधित, एक शायद C ++ एक अमूर्त वर्ग का दृष्टांत कर सकते हैं: यदि आप एक गैर सार वर्ग निकाले जाते हैं Bएक सार में से एक से A, निर्माण के भाग के दौरान की Bउदाहरण है, जो चल रहा मिलकर बनता है Aकी निर्माता, वस्तु के क्रम प्रकार वास्तव में है A। हालांकि केवल अस्थायी।
व्लाद

8
@ जेवर: उन्होंने जो उदाहरण दिया है वह पूरी तरह से गलत है। आपको उससे "अमूर्त वर्ग का उपयोग क्या है" पूछना चाहिए था। यदि आप इसे बढ़ा रहे हैं, तो आप विस्तारित वर्ग का एक उदाहरण क्यों बना रहे हैं? यह एक पूरी तरह से नई वस्तु है, जहां आप बिना किसी डेटा के समाप्त होते हैं ..
लेमन जूस

3
या हो सकता है कि साक्षात्कारकर्ता यह जांचना चाहता था कि आपने अपने बयान के बारे में कितना आश्वस्त किया है कि उसने क्या प्रस्तावित किया था!
सिड

5
उसने आपसे झूठ बोला। जब आप यह इंगित करने में विफल रहे कि यह कोड क्या करता है और यह बताता है कि अनाम उपवर्ग क्या हैं, तो आपने गेंद को गिरा दिया। वह शायद पहले से ही जानता था और यह देखना चाहता था कि क्या आप जानते हैं।
candied_orange

2
यह क्विज़ शो नहीं था, लेकिन नौकरी के लिए इंटरव्यू, सही था? तो क्या होगा यदि जावा, या सी ++, ने अमूर्त कक्षाओं को तत्काल अनुमति दी? आप ऐसा नहीं करेंगे, क्योंकि यह करने के लिए एक चतुर बात नहीं है। ऑब्जेक्टिव-सी में, एब्सट्रैक्ट क्लास केवल कन्वेंशन द्वारा अमूर्त हैं, और उन्हें इंस्टेंट करना एक बग है।
gnasher729

जवाबों:


722

यहाँ, मैं अपनी कक्षा का उदाहरण बना रहा हूँ

नहीं, आप अपने अमूर्त वर्ग का उदाहरण यहाँ नहीं बना रहे हैं। बल्कि आप अपने अमूर्त वर्ग के एक अनाम उपवर्ग का एक उदाहरण बना रहे हैं । और फिर आप उपवर्ग ऑब्जेक्ट की ओर इशारा करते हुए अपने अमूर्त वर्ग संदर्भ पर विधि लागू कर रहे हैं ।

यह व्यवहार जेएलएस में स्पष्ट रूप से सूचीबद्ध है - धारा # 15.9.1 : -

यदि वर्ग उदाहरण सृजन अभिव्यक्ति एक वर्ग निकाय में समाप्त हो जाती है, तो तत्काल होने वाली कक्षा एक अनाम वर्ग है। फिर:

  • यदि टी एक वर्ग को दर्शाता है, तो टी द्वारा नामित वर्ग का एक अनाम प्रत्यक्ष उपवर्ग घोषित किया जाता है। यह एक संकलित समय त्रुटि है यदि टी द्वारा चिह्नित वर्ग अंतिम वर्ग है।
  • यदि T एक इंटरफ़ेस को दर्शाता है, तो ऑब्जेक्ट का एक गुमनाम प्रत्यक्ष उपवर्ग जो T द्वारा नामित इंटरफ़ेस को लागू करता है, घोषित किया जाता है।
  • किसी भी स्थिति में, उपवर्ग का शरीर वर्ग उदाहरण में वर्ग बोध दिया जाता है।
  • क्लास को तत्काल किया जाना अनाम उपवर्ग है।

जोर मेरा।

इसके अलावा, JLS - धारा # 12.5 में , आप ऑब्जेक्ट क्रिएशन प्रोसेस के बारे में पढ़ सकते हैं । मैं यहाँ से एक कथन उद्धृत करूँगा: -

जब भी कोई नया वर्ग उदाहरण बनाया जाता है, तो उसके लिए स्मृति स्थान को कक्षा प्रकार में घोषित सभी उदाहरण चर के लिए कमरे के साथ आवंटित किया जाता है और श्रेणी के प्रत्येक सुपरक्लास में घोषित सभी उदाहरण चर, जिसमें सभी उदाहरण चर छिपे हो सकते हैं, शामिल हैं।

परिणाम के रूप में नई बनाई गई वस्तु के संदर्भ से ठीक पहले, संकेत दिया गया निर्माणकर्ता को निम्नलिखित प्रक्रिया का उपयोग करके नई वस्तु को आरंभ करने के लिए संसाधित किया जाता है:

मेरे द्वारा दिए गए लिंक पर आप पूरी प्रक्रिया के बारे में पढ़ सकते हैं।


व्यावहारिक रूप से यह देखने के लिए कि जिस कक्षा को तत्काल किया जा रहा है वह एक अनाम उप-वर्ग है , आपको बस अपनी दोनों कक्षाओं को संकलित करने की आवश्यकता है। मान लीजिए कि आपने उन वर्गों को दो अलग-अलग फ़ाइलों में रखा है:

My.java:

abstract class My {
    public void myMethod() {
        System.out.print("Abstract");
    }
}

Poly.java:

class Poly extends My {
    public static void main(String a[]) {
        My m = new My() {};
        m.myMethod();
    }
}

अब, अपनी स्रोत फ़ाइलों का संकलन करें:

javac My.java Poly.java

अब निर्देशिका में जहां आपने स्रोत कोड संकलित किया है, आपको निम्न वर्ग फाइलें दिखाई देंगी:

My.class
Poly$1.class  // Class file corresponding to anonymous subclass
Poly.class

उस वर्ग देखें - Poly$1.class। यह नीचे दिए गए कोड का उपयोग करके आप तुरंत उप-लिंक किए गए अनाम उपवर्ग के अनुरूप कंपाइलर द्वारा बनाई गई क्लास फाइल है:

new My() {};

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

सामान्य तौर पर, आपकी कक्षा के सभी अनाम उपवर्गों का नाम इस प्रकार रखा जाएगा:

Poly$1.class, Poly$2.class, Poly$3.class, ... so on

वे संख्याएँ उस क्रम को निरूपित करती हैं जिसमें वे अनाम वर्ग संलग्न वर्ग में दिखाई देते हैं।


172
@coders। सटीक उत्तर है: - आप अपने अमूर्त वर्ग को तुरंत नहीं भेज सकते हैं, हालाँकि आप अपने सार वर्ग के एक ठोस उपवर्ग को तुरंत कर सकते हैं।
रोहित जैन 16

16
एक पंक्ति में आप कह सकते हैं: - आप कभी भी एक अमूर्त वर्ग का संकेत नहीं दे सकते। यह एक अमूर्त वर्ग का उद्देश्य है।
राहुल त्रिपाठी

66
ऐसा लगता है कि साक्षात्कारकर्ता ने आपके जवाब में अधिक निवेश किया था, वह आपके मुकाबले में था ...
नील टी।

7
के अनुसार एक और टिप्पणी (एक साथ JLS संदर्भ ), "एक वस्तु कहा जाता है कि अपने वर्ग की और उसके वर्ग के सभी सुपर-क्लास का एक उदाहरण होने के लिए" - इसलिए, हम वास्तव में तकनीकी रूप से अमूर्त वर्ग यहाँ का उदाहरण बनाकर नहीं कर रहे हैं? यानी अमूर्त वर्ग को तत्काल?
अर्धजी

6
@ARS मैं कहना चाहता हूँ वहाँ एक जा रहा है के बीच एक अंतर है कि instance ofऔर instantiating। आप केवल एक वर्ग को इंस्टेंट करते हैं, जबकि आपके द्वारा बनाई गई वस्तु विरासत के कारण कई वर्गों का उदाहरण हो सकती है।
साइमन फोर्सबर्ग

89

उपरोक्त एक अनाम आंतरिक वर्ग को तात्कालिक बनाता है जो myअमूर्त वर्ग का उपवर्ग है । यह कड़ाई से खुद को अमूर्त वर्ग के बराबर नहीं है। OTOH, प्रत्येक उपवर्ग का उदाहरण इसके सभी सुपर वर्गों और इंटरफेस का एक उदाहरण है, इसलिए अधिकांश अमूर्त वर्ग वास्तव में अपने ठोस उपवर्गों में से किसी एक को तात्कालिक करके त्वरित होते हैं।

अगर साक्षात्कारकर्ता ने सिर्फ "गलत कहा!" बिना समझाए, और इस उदाहरण को दिया, एक अद्वितीय प्रतिधारण के रूप में, मुझे लगता है कि वह नहीं जानता कि वह किस बारे में बात कर रहा है।


10
कड़े शब्दों में, सार सुपरक्लास त्वरित नहीं है। यह कंस्ट्रक्टर इंस्टेंस इंस्टेंस वेरिएबल को इनिशियलाइज़ करने के लिए कहा जाता है।
धारणा 20

4
हाँ यह है: यह subclassInstance instanceof SuperClassसच है, तो वस्तु सुपरक्लास का एक उदाहरण है, जिसका अर्थ है कि सुपरक्लास को अस्थिर किया गया है। लेकिन यह सिर्फ शब्दार्थ नाइटिंग है।
जेबी निज़ेट

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

11
JLS का पैरा 4.12.6 कहता है: "एक वस्तु को उसके वर्ग की और उसके वर्ग के सभी सुपरक्लास की एक आवृत्ति कहा जाता है।"
जेबी निज़ेट

85

= my() {};इसका मतलब है कि एक गुमनाम कार्यान्वयन है, न कि किसी वस्तु का सरल तात्कालिकता, जो होना चाहिए था = my():। आप कभी भी एक अमूर्त वर्ग को नहीं रोक सकते।


30

बस आपके द्वारा किए जा सकने वाले अवलोकन:

  1. क्यों polyबढ़ाता है my? यह बेकार है ...
  2. संकलन का परिणाम क्या है? तीन फाइलें: my.class, poly.classऔरpoly$1.class
  3. अगर हम उस तरह के एक अमूर्त वर्ग को तुरंत कर सकते हैं, तो हम एक इंटरफ़ेस को भी त्वरित कर सकते हैं ... अजीब ...


क्या हम एक अमूर्त वर्ग को तात्कालिक कर सकते हैं?

नहीं, हम नहीं कर सकते। हम क्या कर सकते हैं, एक अनाम वर्ग बनाएं (जो कि तीसरी फ़ाइल है) और इसे तुरंत लिखें।


सुपर क्लास इंस्टेंटेशन के बारे में क्या?

अमूर्त सुपर क्लास हमारे द्वारा तात्कालिक नहीं, बल्कि जावा से है।

संपादित करें: उसे यह परीक्षण करने के लिए कहें

public static final void main(final String[] args) {
    final my m1 = new my() {
    };
    final my m2 = new my() {
    };
    System.out.println(m1 == m2);

    System.out.println(m1.getClass().toString());
    System.out.println(m2.getClass().toString());

}

आउटपुट है:

false
class my$1
class my$2

अवलोकन 3 के लिए +1: उदाहरण के लिए, हम कर सकते हैं Serializable s = new Serializable() {};(जो कि बहुत बेकार है) और यदि आपके कोड पर टैग दिया गया है class my$3(या जो भी वर्ग और संख्या को संलग्न करना होगा )
मोनिका को बहाल करें - notmaynard

18

आप बस एक लाइन में जवाब दे सकते हैं

नहीं , आप कभी भी सार वर्ग का उदाहरण नहीं दे सकते

लेकिन, साक्षात्कारकर्ता अभी भी सहमत नहीं है, तो आप उसे / उसे बता सकते हैं

आप केवल इतना कर सकते हैं कि आप एक अनाम वर्ग बना सकते हैं।

और, अनाम वर्ग के अनुसार, एक ही स्थान / रेखा पर वर्ग घोषित और त्वरित

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


17

तकनीकी भाग को अन्य उत्तरों में अच्छी तरह से कवर किया गया है, और यह मुख्य रूप से समाप्त होता है:
"वह गलत है, वह सामान नहीं जानता है, उसे एसओ में शामिल होने के लिए कहें और यह सब साफ हो जाए :)"

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

पुनश्च: मैं नहीं जानता कि क्यों लेकिन मुझे लगता है कि साक्षात्कारकर्ता ने इस पोस्ट को पढ़ा है।


13

अमूर्त वर्गों को तत्काल नहीं किया जा सकता है, लेकिन उन्हें उपवर्गित किया जा सकता है। यह लिंक देखें

सबसे अच्छा उदाहरण है

यद्यपि कैलेंडर वर्ग में एक सार पद्धति getInstance () है , लेकिन जब आप कहते हैंCalendar calc=Calendar.getInstance();

कैल्क वर्ग ग्रेगोरियन कैलेन्डर के वर्ग उदाहरण का उल्लेख कर रहा है "ग्रेगोरियन कैलेन्डर कैलेंडर का विस्तार करता है "

इनफेक्ट एनॉनिमस इनर टाइप आपको एब्स्ट्रैक्ट क्लास का नो-नाम सबक्लास और इसका एक उदाहरण बनाने की अनुमति देता है


11

तकनीकी उत्तर

अमूर्त वर्गों को तुरंत नहीं किया जा सकता है - यह परिभाषा और डिजाइन द्वारा है।

JLS, अध्याय 8 से। कक्षाएं:

एक नामित वर्ग को सार (class8.1.1.1) घोषित किया जा सकता है और इसे अपूर्ण रूप से लागू किए जाने पर सार घोषित किया जाना चाहिए; ऐसे वर्ग को त्वरित नहीं किया जा सकता है, लेकिन उपवर्गों द्वारा बढ़ाया जा सकता है।

JSE 6 से java doc के लिए Classes.newInstance ():

तत्कालकरण - यदि यह वर्ग एक सार वर्ग, एक अंतरफलक, एक सरणी वर्ग, एक आदिम प्रकार, या शून्य का प्रतिनिधित्व करता है; या यदि कक्षा में कोई अशक्त निर्माता नहीं है; या अगर तात्कालिकता किसी अन्य कारण से विफल हो जाती है।

आप निश्चित रूप से, एक अमूर्त वर्ग (एक गुमनाम उपवर्ग सहित) के एक ठोस उपवर्ग को तुरंत कर सकते हैं और एक सार प्रकार के लिए एक वस्तु संदर्भ का टाइपकास्ट भी कर सकते हैं।

इस पर एक अलग कोण - टीमप्ले और सोशल इंटेलिजेंस:

इस तरह की तकनीकी गलतफहमी वास्तविक दुनिया में अक्सर होती है जब हम जटिल प्रौद्योगिकियों और कानूनी विनिर्देशों से निपटते हैं।

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

कौन जानता है - हालांकि संभावना नहीं है, यह संभव है कि साक्षात्कारकर्ता ने जानबूझकर आपको एक चुनौतीपूर्ण स्थिति में डालने के लिए एक छोटा सा संघर्ष / गलतफहमी पेश की और देखें कि आप भावनात्मक और सामाजिक रूप से कैसे व्यवहार करते हैं। सहकर्मियों के साथ अनुग्रह और रचनात्मक रहें, वरिष्ठों से सलाह का पालन करें, और किसी भी चुनौती / गलतफहमी को हल करने के लिए साक्षात्कार के बाद ईमेल या फोन कॉल के माध्यम से पालन करें। शो आप प्रेरित और विस्तार उन्मुख हैं।


7

यह एक अच्छी तरह से स्थापित तथ्य यह है कि है abstract classसकते हैं नहीं instantiated जा के रूप में हर किसी को जवाब दे दिया।

जब प्रोग्राम गुमनाम वर्ग को परिभाषित करता है, तो संकलक वास्तव में अलग-अलग नाम से एक नया वर्ग बनाता है (पैटर्न है EnclosedClassName$nजहां nअनाम वर्ग संख्या है)

इसलिए यदि आप इस जावा वर्ग को हटा देते हैं तो आपको नीचे जैसा कोड मिलेगा:

मेरी कक्षा

abstract class my { 
    public void mymethod() 
    { 
        System.out.print("Abstract"); 
    }
} 

पॉली $ 1.क्लास ("अनाम वर्ग" का उत्पन्न वर्ग)

class poly$1 extends my 
{
} 

ploly.cass

public class poly extends my
{
    public static void main(String[] a)
    {
        my m = new poly.1(); // instance of poly.1 class NOT the abstract my class

        m.mymethod();
    }
}

4

नहीं, आप एक अमूर्त वर्ग को तात्कालिक नहीं कर सकते हैं। हम केवल अनाम वर्ग को तात्कालिक बनाते हैं। अमूर्त वर्ग में हम सार विधियों की घोषणा करते हैं और केवल ठोस विधियों को परिभाषित करते हैं।


4

सार वर्ग के बारे में

  • एक अमूर्त वर्ग की वस्तु नहीं बना सकते
  • चर बना सकते हैं (डेटाैटिप्स की तरह व्यवहार कर सकते हैं)
  • यदि बच्चा माता-पिता की कम से कम एक सार पद्धति को ओवरराइड नहीं कर सकता है, तो बच्चा भी सार हो जाता है
  • बच्चे वर्ग के बिना सार कक्षाएं बेकार हैं

एक सार वर्ग का उद्देश्य आधार की तरह व्यवहार करना है। वंशानुगत पदानुक्रम में आप शीर्ष की ओर सार कक्षाएं देखेंगे।


3

आप कह सकते हैं:
हम एक अमूर्त वर्ग को नहीं रोक सकते हैं, लेकिन हम अमूर्त वर्ग के अंत में शरीर को लागू करने के रूप में newजोड़कर एक अनाम वर्ग उदाहरण बनाने के लिए कीवर्ड का उपयोग कर सकते हैं {}


3

कक्षा का विस्तार करने का मतलब यह नहीं है कि आप कक्षा को तुरंत शुरू कर रहे हैं। दरअसल, आपके मामले में आप उपवर्ग का एक उदाहरण बना रहे हैं।

मुझे पूरा यकीन है कि अमूर्त कक्षाएं आरंभ करने की अनुमति नहीं देती हैं। तो, मैं कहूंगा कि आप किसी अमूर्त वर्ग को नहीं देख सकते। लेकिन, आप इसे बढ़ा सकते हैं / विरासत में दे सकते हैं।

आप एक अमूर्त वर्ग को तुरंत नहीं दिखा सकते हैं। लेकिन इसका मतलब यह नहीं है कि आपको परोक्ष रूप से कक्षा का एक उदाहरण (मूल रूप से मूल सार वर्ग का उदाहरण नहीं) नहीं मिल सकता है। मेरा मतलब है कि आप orginial अमूर्त वर्ग को तुरंत नहीं कर सकते, लेकिन आप कर सकते हैं:

  1. एक खाली वर्ग बनाएँ
  2. इसे अमूर्त वर्ग से प्राप्त करें
  3. घबराए हुए वर्ग को त्वरित करें

तो आप एक वर्ग में व्युत्पन्न वर्ग उदाहरण के माध्यम से सभी तरीकों और गुणों तक पहुँच प्राप्त करते हैं।


2

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

   public abstract class AbstractGridManager {
        private LifecicleAlgorithmIntrface lifecicleAlgorithm;
        // ... more private fields

        //Method implemented in concrete Manager implementors 
        abstract public Grid initGrid();

        //Methods common to all implementors
        public Grid calculateNextLifecicle(Grid grid){
            return this.getLifecicleAlgorithm().calculateNextLifecicle(grid);
        }

        public LifecicleAlgorithmIntrface getLifecicleAlgorithm() {
            return lifecicleAlgorithm;
        }
        public void setLifecicleAlgorithm(LifecicleAlgorithmIntrface lifecicleAlgorithm) {
            this.lifecicleAlgorithm = lifecicleAlgorithm;
        }
        // ... more common logic and getters-setters pairs
    }

ठोस कार्यान्वयनकर्ता को केवल सार के रूप में घोषित तरीकों को लागू करने की आवश्यकता होती है, लेकिन उन कक्षाओं में लागू किए गए तर्क तक पहुंच होगी जो एक सार वर्ग में हैं, जिन्हें सार घोषित नहीं किया गया है:

public class FileInputGridManager extends AbstractGridManager {

private String filePath;

//Method implemented in concrete Manager implementors 
abstract public Grid initGrid();

public class FileInputGridManager extends AbstractGridManager {

    private String filePath;

    //Method implemented in concrete Manager implementors 
    abstract public Grid initGrid();

    public Grid initGrid(String filePath) {
        List<Cell> cells = new ArrayList<>();
        char[] chars;
        File file = new File(filePath); // for example foo.txt
        // ... more logic
        return grid;
    }
}

फिर अंत में कारखाना कुछ इस तरह दिखता है:

public class GridManagerFactory {
    public static AbstractGridManager getGridManager(LifecicleAlgorithmIntrface lifecicleAlgorithm, String... args){
        AbstractGridManager manager = null;

        // input from the command line
        if(args.length == 2){
            CommandLineGridManager clManager = new CommandLineGridManager();
            clManager.setWidth(Integer.parseInt(args[0]));
            clManager.setHeight(Integer.parseInt(args[1]));
            // possibly more configuration logic
            ...
            manager = clManager;
        } 
        // input from the file
        else if(args.length == 1){
            FileInputGridManager fiManager = new FileInputGridManager();
            fiManager.setFilePath(args[0]);
            // possibly more method calls from abstract class
            ...
            manager = fiManager ;
        }
        //... more possible concrete implementors
        else{
            manager = new CommandLineGridManager();
        }
        manager.setLifecicleAlgorithm(lifecicleAlgorithm);
        return manager;
    }
}

AbstractGridManager के रिसीवर उस पर तरीकों को कॉल करेंगे और तर्क प्राप्त करेंगे, कंक्रीट डिसेंडर (और आंशिक रूप से अमूर्त वर्ग विधियों में) को बिना यह जाने कि उसे क्या ठोस कार्यान्वयन मिला है। इसे नियंत्रण या निर्भरता इंजेक्शन के व्युत्क्रम के रूप में भी जाना जाता है।


2

नहीं, हम अमूर्त वर्ग की वस्तु नहीं बना सकते हैं, लेकिन अमूर्त वर्ग का संदर्भ चर बना सकते हैं। संदर्भ चर का उपयोग व्युत्पन्न वर्गों की वस्तुओं (सार वर्ग के उप वर्गों) को संदर्भित करने के लिए किया जाता है

यहाँ उदाहरण है जो इस अवधारणा को दिखाता है

abstract class Figure { 

    double dim1; 

    double dim2; 

    Figure(double a, double b) { 

        dim1 = a; 

        dim2 = b; 

    } 

    // area is now an abstract method 

    abstract double area(); 

    }


    class Rectangle extends Figure { 
        Rectangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for rectangle 
    double area() { 
        System.out.println("Inside Area for Rectangle."); 
        return dim1 * dim2; 
    } 
}

class Triangle extends Figure { 
    Triangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for right triangle 
    double area() { 
        System.out.println("Inside Area for Triangle."); 
        return dim1 * dim2 / 2; 
    } 
}

class AbstractAreas { 
    public static void main(String args[]) { 
        // Figure f = new Figure(10, 10); // illegal now 
        Rectangle r = new Rectangle(9, 5); 
        Triangle t = new Triangle(10, 8); 
        Figure figref; // this is OK, no object is created 
        figref = r; 
        System.out.println("Area is " + figref.area()); 
        figref = t; 
        System.out.println("Area is " + figref.area()); 
    } 
}

यहाँ हम देखते हैं कि हम टाइप फिगर का ऑब्जेक्ट नहीं बना सकते हैं लेकिन हम टाइप फिगर का एक रेफरेंस वैरिएबल बना सकते हैं। यहाँ हमने टाइप फिगर का एक रेफरेंस वेरिएबल बनाया है और क्लास रेक्टेंगल और ट्राइएंगल की वस्तुओं को संदर्भित करने के लिए फिगर क्लास रेफरेंस वेरिएबल का उपयोग किया जाता है।


0

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.