जावा में सार वर्ग


274

जावा में एक "अमूर्त वर्ग" क्या है?


35
+1 यह सवाल इतना बुनियादी और मौलिक है, यह एसओ के लिए एक क्लासिक है। मुझे आश्चर्य है कि यह यहाँ से पहले नहीं पूछा गया है।
युवल

6
क्लेमेंट की टिप्पणी के लिए -1 (यदि मैं कर सकता था); lmgtfy एक उपयोगी उत्तर नहीं है। क्यों के लिए, पढ़ें यह मेटा.stackexchange.com/questions/5280/embrace-the-non-googler
Jonik

26
@tuergeist। यदि यह Google से आसान है, तो यह अप्रासंगिक है, क्योंकि इससे पहले SO पर नहीं पूछा गया था। इसके अलावा, कौन कहता है कि प्रोग्रामिंग भाषाओं के बारे में शुरुआती सवाल SO पर नहीं हैं?
जोनीक

12
SO के बारे में एक बात मुझे अच्छी लगती है कि आपको एक ऐसा उत्तर मिलेगा जो गाढ़ा है, अच्छी तरह से रखा गया है और बिना किसी सामान्य बीएस की बात के बाकी वेब पर मिल रहा है ... वैसे भी कुछ ऐसा ही है। सवाल के लिए +1!
एंडर्स हैन्सन

1
एसओ सिर्फ लंबी पूंछ के लिए नहीं माना जाता है! J & J ने पॉडकास्ट 56 के आसपास भी इस बारे में बात की ...
kwutchak

जवाबों:


342

एक अमूर्त वर्ग एक ऐसा वर्ग है जिसे त्वरित नहीं किया जा सकता है। एक अमूर्त वर्ग का उपयोग एक अंतर्निहित उपवर्ग का निर्माण करके किया जाता है जिसे तत्काल किया जा सकता है। अनुगामी उपवर्ग के लिए एक सार वर्ग कुछ चीजें करता है:

  1. उन विधियों को परिभाषित करें जिनका उपयोग अंतर्निहित उपवर्ग द्वारा किया जा सकता है।
  2. अमूर्त तरीकों को परिभाषित करें जो विरासत में उपवर्ग को लागू करना चाहिए।
  3. एक सामान्य इंटरफ़ेस प्रदान करें जो उपवर्ग को अन्य सभी उपवर्गों के साथ इंटरचेंज करने की अनुमति देता है।

यहाँ एक उदाहरण है:

abstract public class AbstractClass
{
    abstract public void abstractMethod();
    public void implementedMethod() { System.out.print("implementedMethod()"); }
    final public void finalMethod() { System.out.print("finalMethod()"); }
}

ध्यान दें कि "abstractMethod ()" में कोई विधि निकाय नहीं है। इस वजह से, आप निम्न कार्य नहीं कर सकते:

public class ImplementingClass extends AbstractClass
{
    // ERROR!
}

कोई तरीका नहीं है जो लागू करता है abstractMethod()! इसलिए जेवीएम के लिए यह जानने का कोई तरीका नहीं है कि ऐसा करने के बाद क्या करना चाहिए new ImplementingClass().abstractMethod()

यहाँ एक सही है ImplementingClass

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
}

ध्यान दें कि आपको परिभाषित implementedMethod()या नहीं करना है finalMethod()। वे पहले से ही परिभाषित थे AbstractClass

यहाँ एक और सही है ImplementingClass

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
}

इस मामले में, आपने ओवरराइड किया है implementedMethod()

हालाँकि, finalकीवर्ड के कारण, निम्नलिखित संभव नहीं है।

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
    public void finalMethod() { System.out.print("ERROR!"); }
}

आप की वजह से कार्यान्वयन ऐसा नहीं कर सकते finalMethod()में AbstractClassकी अंतिम कार्यान्वयन के रूप में चिह्नित किया गया है finalMethod()कभी नहीं अन्य कार्यान्वयन की अनुमति दी जाएगी,:।

अब आप एक अमूर्त वर्ग को दो बार भी लागू कर सकते हैं :

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
}

// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("second abstractMethod()"); }
}

अब कहीं आप दूसरी विधि लिख सकते थे।

public tryItOut()
{
    ImplementingClass a = new ImplementingClass();
    AbstractClass b = new ImplementingClass();

    a.abstractMethod();    // prints "abstractMethod()"
    a.implementedMethod(); // prints "Overridden!"     <-- same
    a.finalMethod();       // prints "finalMethod()"

    b.abstractMethod();    // prints "abstractMethod()"
    b.implementedMethod(); // prints "Overridden!"     <-- same
    b.finalMethod();       // prints "finalMethod()"

    SecondImplementingClass c = new SecondImplementingClass();
    AbstractClass d = new SecondImplementingClass();

    c.abstractMethod();    // prints "second abstractMethod()"
    c.implementedMethod(); // prints "implementedMethod()"
    c.finalMethod();       // prints "finalMethod()"

    d.abstractMethod();    // prints "second abstractMethod()"
    d.implementedMethod(); // prints "implementedMethod()"
    d.finalMethod();       // prints "finalMethod()"
}

ध्यान दें कि भले ही हमने bएक AbstractClassप्रकार घोषित किया हो , यह प्रदर्शित करता है "Overriden!"। इसका कारण यह है कि जिस वस्तु का हमने तात्पर्य किया था वह वास्तव में एक थी ImplementingClass, जिसकी implementedMethod()निश्चित रूप से अधिकता है। (आपने इसे बहुरूपता के रूप में संदर्भित देखा होगा।)

यदि हम किसी विशेष उपवर्ग के लिए विशिष्ट सदस्य तक पहुँचना चाहते हैं, तो हमें पहले उस उपवर्ग में नीचे उतरना होगा:

// Say ImplementingClass also contains uniqueMethod()
// To access it, we use a cast to tell the runtime which type the object is
AbstractClass b = new ImplementingClass();
((ImplementingClass)b).uniqueMethod();

अंत में, आप निम्न कार्य नहीं कर सकते:

public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
    ... // implementation
}

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

public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
    ... // implementation
}

यहाँ एक उदाहरण इंटरफ़ेस है:

interface InterfaceA
{
    void interfaceMethod();
}

यह मूल रूप से समान है:

abstract public class InterfaceA
{
    abstract public void interfaceMethod();
}

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

निम्नलिखित अवैध है:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

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


5
@Imagist -1 के गलत विवरण के लिए c.implementedMethod (); // प्रिंट "कार्यान्वितमेथोड ()", यह "ओवररिडेन!" हमेशा
सचिन कुमार

2
@ साचिन ने यह समझने के लिए कि मुझे "कार्यान्वित मैथोड ()" क्यों छापना है और फिर मैंने उनकी टिप्पणी देखी, आधे घंटे का समय बर्बाद कर दिया। क्या जावा के साथ कुछ बदल गया या दूसरों ने सिर्फ गलती की अनदेखी की?
रौनक

@SachinKumar लेखक की प्रतिक्रिया की कमी के कारण, मैंने इस त्रुटि को ठीक करने के लिए इसे अपने ऊपर ले लिया है। CMIIW।
मतीन उल्हाक

@SachinKumar मुझे यहाँ खेल में थोड़ी देर हो गई है, लेकिन क्या आप कहेंगे कि C ++ हैडर फ़ाइल में एक अच्छा सादृश्य एक विधि घोषणा (लेकिन कोई कार्यान्वयन) नहीं होगा?
श्विट्ज

5
@SachinKumar c.implementedMethod()" ओवररिडेन !" क्यों छपेगा ? SecondImplementingClassओवरराइड नहीं करता है implementedMethod()
जॉन रेड

75

एक जावा वर्ग निम्नलिखित शर्तों के तहत अमूर्त हो जाता है:

1. कम से कम एक विधि को सार के रूप में चिह्नित किया गया है:

public abstract void myMethod()

उस स्थिति में कंपाइलर आपको पूरी कक्षा को सार के रूप में चिह्नित करने के लिए मजबूर करता है।

2. वर्ग को सार के रूप में चिह्नित किया गया है:

abstract class MyClass

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

सामान्य उपयोग:

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

एक सार वर्ग को तत्काल नहीं किया जा सकता है, लेकिन आप एक सार वर्ग के आधार पर एक ठोस वर्ग बना सकते हैं, जिसे तब त्वरित किया जा सकता है। ऐसा करने के लिए आपको अमूर्त वर्ग से विरासत में लेना होगा और अमूर्त विधियों को ओवरराइड करना होगा, यानी उन्हें लागू करना होगा।


1
नाइटपिक: दूसरी 'स्थिति' निरर्थक है, क्योंकि आप केवल एक कक्षा में एक सार पद्धति की घोषणा कर सकते हैं जिसे स्पष्ट रूप से सार के रूप में घोषित किया गया है।
स्टीफन C

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

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

1
यह सीधे तौर पर गलत है। एक अमूर्त वर्ग के लिए कोई सार विधियाँ नहीं होती हैं। आप तरीकों के बिना, या केवल ठोस तरीकों के साथ एक सार वर्ग बना सकते हैं।
जोनर

1
खेल के लिए 10 साल की देरी, लेकिन यह सबसे सटीक जवाब है। @ क्या आपको लगता है कि मुझे लगता है कि उत्तर के साथ भ्रमित हैं। मुझे यकीन है कि यह निहित है कि abstractकीवर्ड एक वर्ग के सार के लिए आवश्यक है। लेकिन एक ठोस वर्ग में एक विधि नहीं हो सकती । इस प्रकार यदि आपकी कक्षा में एक विधि है, तो उसे संकलक के लिए एक वर्ग के रूप में घोषित किया जाना है । abstract abstractabstract
रकीब

24

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

अमूर्त वर्ग की मुख्य बातें

  • एक अमूर्त वर्ग में अमूर्त विधियाँ हो सकती हैं या नहीं हो सकती हैं। यह गैर अमूर्त विधियाँ हो सकती हैं।

    एक अमूर्त विधि एक ऐसी विधि है जो बिना क्रियान्वयन के (बिना ब्रेसिज़ के, और अर्धविराम के बाद) घोषित की जाती है:

    पूर्व: abstract void moveTo(double deltaX, double deltaY);

  • यदि किसी वर्ग में कम से कम एक सार विधि है तो उस वर्ग को सार होना चाहिए

  • अमूर्त वर्गों को तत्काल नहीं किया जा सकता है (आपको सार वर्ग की वस्तु बनाने की अनुमति नहीं है)

  • एक अमूर्त वर्ग का उपयोग करने के लिए, आपको इसे दूसरे वर्ग से विरासत में प्राप्त करना होगा। इसमें सभी अमूर्त विधियों को कार्यान्वयन प्रदान करें।

  • यदि आपको एक अमूर्त वर्ग विरासत में मिला है, तो आपको इसमें सभी सार विधियों को क्रियान्वयन प्रदान करना होगा।

डिक्लेयर एब्सट्रेक्ट क्लासabstract डिक्लेरेशन के दौरान क्लास से पहले कीवर्ड निर्दिष्ट करना इसे अमूर्त बनाता है। नीचे दिए गए कोड पर एक नज़र डालें:

abstract class AbstractDemo{ }

डिक्लेयर अमूर्त विधिabstract घोषणा के दौरान विधि से पहले कीवर्ड निर्दिष्ट करना इसे अमूर्त बनाता है। नीचे दिए गए कोड पर एक नज़र डालें,

abstract void moveTo();//no body

हमें अमूर्त वर्गों की आवश्यकता क्यों है

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

अमूर्त सुपरक्लास के लिए यह एक आदर्श स्थिति है। आप समानताओं का लाभ उठा सकते हैं, और सभी ग्राफिक वस्तुओं को एक ही अमूर्त मूल वस्तु (उदाहरण के लिए GraphicObject) से प्राप्त करने की घोषणा कर सकते हैं, जैसा कि निम्नलिखित आकृति में दिखाया गया है। यहां छवि विवरण दर्ज करें

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

abstract class GraphicObject {

  void moveTo(int x, int y) {
    // Inside this method we have to change the position of the graphic 
    // object according to x,y     
    // This is the same in every GraphicObject. Then we can implement here. 
  }

  abstract void draw(); // But every GraphicObject drawing case is 
                        // unique, not common. Then we have to create that 
                        // case inside each class. Then create these    
                        // methods as abstract 
  abstract void resize();
}

उप-वर्गों में अमूर्त विधि का उपयोग, प्रत्येक गैर अमूर्त उपवर्ग GraphicObject, जैसे कि Circleऔर Rectangle, के लिए drawऔर resizeतरीकों के लिए कार्यान्वयन प्रदान करना चाहिए ।

class Circle extends GraphicObject {
  void draw() {
    //Add to some implementation here
  }
  void resize() {
    //Add to some implementation here   
  }
}
class Rectangle extends GraphicObject {
  void draw() {
    //Add to some implementation here
  }
  void resize() {
    //Add to some implementation here
  }
}

mainविधि के अंदर आप इस तरह से सभी तरीकों को कॉल कर सकते हैं:

public static void main(String args[]){
   GraphicObject c = new Circle();
   c.draw();
   c.resize();
   c.moveTo(4,5);   
}

जावा में अमूर्तता प्राप्त करने के तरीके

जावा में अमूर्तता प्राप्त करने के दो तरीके हैं

  • सार वर्ग (0 से 100%)
  • इंटरफ़ेस (100%)

रचनाकारों, डेटा सदस्यों, विधियों, आदि के साथ सार वर्ग

abstract class GraphicObject {

  GraphicObject (){
    System.out.println("GraphicObject  is created");
  }
  void moveTo(int y, int x) {
       System.out.println("Change position according to "+ x+ " and " + y);
  }
  abstract void draw();
}

class Circle extends GraphicObject {
  void draw() {
    System.out.println("Draw the Circle");
  }
}

class TestAbstract {  
 public static void main(String args[]){

   GraphicObject  grObj = new Circle ();
   grObj.draw();
   grObj.moveTo(4,6);
 }
}

आउटपुट:

GraphicObject  is created
Draw the Circle
Change position according to 6 and 4

दो नियम याद रखें:

  • यदि कक्षा में कुछ अमूर्त विधियाँ और कुछ ठोस विधियाँ हैं, तो इसे एक abstractवर्ग के रूप में घोषित करें ।

  • यदि कक्षा में केवल सार विधियां हैं, तो इसे एक के रूप में घोषित करें interface

संदर्भ:


MoveTo में पैरामीटर x और y का क्रम ऊपर के उदाहरण में भिन्न क्यों है, नीचे दिए गए उदाहरण और नीचे दिए गए उदाहरण से आउटपुट? यदि हम इंटरफेस और अमूर्त कक्षाओं जैसी अवधारणाओं के महत्व को स्पष्ट करने की कोशिश कर रहे हैं, तो क्या हमें उसी फ़ंक्शन हस्ताक्षर का उपयोग नहीं करना चाहिए, जिस तरह के इंटरफेस या अमूर्त वर्ग हम लगातार लागू कर रहे हैं या बढ़ा रहे हैं?
जोनाथन Rys

दो नियम इसे दूर करते हैं
LiNKeR

4

यह एक ऐसा वर्ग है जिसे त्वरित नहीं किया जा सकता है, और संभवतया, इसे लागू करने वाले अमूर्त तरीकों को लागू करने के लिए कक्षाओं को लागू करने के लिए मजबूर करता है।


3

सीधे शब्दों में, आप एक अमूर्त वर्ग के बारे में सोच सकते हैं जैसे कि इंटरफ़ेस थोड़ा अधिक क्षमताओं के साथ।

आप एक इंटरफ़ेस को रोक नहीं सकते, जो एक अमूर्त वर्ग के लिए भी है।

अपने इंटरफ़ेस पर आप केवल विधि शीर्षकों को परिभाषित कर सकते हैं और सभी कार्यान्वयनकर्ता को उन सभी को लागू करने के लिए मजबूर किया जाता है। अमूर्त वर्ग पर आप अपने विधि शीर्षकों को भी परिभाषित कर सकते हैं लेकिन यहाँ - इंटरफ़ेस के अंतर के लिए - आप विधि के शरीर (आमतौर पर एक डिफ़ॉल्ट कार्यान्वयन) को भी परिभाषित कर सकते हैं। इसके अलावा जब अन्य कक्षाएं विस्तारित होती हैं (ध्यान दें, लागू न करें और इसलिए आप प्रति बच्चे वर्ग में सिर्फ एक सार वर्ग हो सकते हैं ) आपका अमूर्त वर्ग, वे आपके सार वर्ग के आपके सभी तरीकों को लागू करने के लिए मजबूर नहीं होते हैं, जब तक कि आप एक सार पद्धति निर्दिष्ट नहीं करते हैं ( इस तरह के मामले में यह इंटरफेस के लिए काम करता है, आप विधि बॉडी को परिभाषित नहीं कर सकते हैं)।

public abstract class MyAbstractClass{
  public abstract void DoSomething();
}

अन्यथा एक अमूर्त वर्ग के सामान्य तरीकों के लिए, "विरासत" या तो डिफ़ॉल्ट व्यवहार का उपयोग कर सकता है या इसे हमेशा की तरह ओवरराइड कर सकता है।

उदाहरण:

public abstract class MyAbstractClass{

  public int CalculateCost(int amount){
     //do some default calculations
     //this can be overriden by subclasses if needed
  }

  //this MUST be implemented by subclasses
  public abstract void DoSomething();
}

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

लेकिन यह हो सकता है। यह हो सकता है कि वह सिर्फ यह जानता है कि एक इंटरफ़ेस क्या है और यह कैसे काम करता है, और फिर वह अमूर्त कक्षाओं में आता है और आश्चर्य करता है कि किसी को उनकी आवश्यकता क्यों होनी चाहिए। ऐसा नहीं हो सकता है?
जुरी

3

ओरेकल डॉक्यूमेंटेशन से

सार विधियाँ और कक्षाएं:

एक अमूर्त वर्ग एक ऐसा वर्ग है जिसे अमूर्त घोषित किया जाता है - इसमें अमूर्त विधियाँ शामिल हो सकती हैं या नहीं भी हो सकती हैं

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

एक अमूर्त विधि एक ऐसी विधि है जो कार्यान्वयन के बिना घोषित की जाती है (ब्रेसिज़ के बिना, और अर्धविराम के बाद), इस तरह से:

abstract void moveTo(double deltaX, double deltaY);

यदि किसी वर्ग में सार विधियां शामिल हैं, तो कक्षा को ही सार घोषित किया जाना चाहिए, जैसे:

public abstract class GraphicObject {
   // declare fields
   // declare nonabstract methods
   abstract void draw();
}

जब एक अमूर्त वर्ग को उपवर्गित किया जाता है, तो उपवर्ग आमतौर पर अपने मूल वर्ग के सभी अमूर्त तरीकों के लिए कार्यान्वयन प्रदान करता है। हालांकि, यदि ऐसा नहीं होता है, तो उपवर्ग को भी सार घोषित किया जाना चाहिए

चूंकि abstract classesऔर interfacesसंबंधित हैं, एसई प्रश्नों के नीचे एक नज़र है:

इंटरफ़ेस और अमूर्त वर्ग के बीच अंतर क्या है?

मुझे इंटरफ़ेस और अमूर्त वर्ग के बीच अंतर कैसे समझाया जाना चाहिए?


3

यहाँ अपने उत्तर प्राप्त करें:

जावा में सार वर्ग बनाम इंटरफ़ेस

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

BTW - वे प्रश्न हैं जो आपने हाल ही में पूछे हैं। प्रतिष्ठा बनाने के लिए एक नए प्रश्न के बारे में सोचें ...

संपादित करें:

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


और इसीलिए मैंने 'कम्युनिटी विकी' चेक किया - किसी को उन सवालों पर प्रतिक्रिया देने के माध्यम से प्रतिष्ठा नहीं बढ़ानी चाहिए;)
एंड्रियास

1

इन सभी पदों के लिए थोड़ा अतिरिक्त।

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


1

एक अमूर्त वर्ग को सीधे तात्कालिक नहीं किया जा सकता है, लेकिन इसे प्रयोग करने योग्य माना जाना चाहिए। एक वर्ग का सार होना चाहिए अगर इसमें सार विधियाँ हैं: या तो सीधे

abstract class Foo {
    abstract void someMethod();
}

या अप्रत्यक्ष रूप से

interface IFoo {
    void someMethod();
}

abstract class Foo2 implements IFoo {
}

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

abstract class Foo3 {
}

class Bar extends Foo3 {

}

Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!

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

एक और लगातार पैटर्न अमूर्त वर्ग में मुख्य कार्यक्षमता को लागू करने और एक अमूर्त विधि में एल्गोरिथ्म के एक हिस्से को परिभाषित करने के लिए एक विस्तृत वर्ग द्वारा लागू किया जाता है। मूर्खतापूर्ण उदाहरण:

abstract class Processor {
    protected abstract int[] filterInput(int[] unfiltered);

    public int process(int[] values) {
        int[] filtered = filterInput(values);
        // do something with filtered input
    }
}

class EvenValues extends Processor {
    protected int[] filterInput(int[] unfiltered) {
        // remove odd numbers
    }
}

class OddValues extends Processor {
    protected int[] filterInput(int[] unfiltered) {
        // remove even numbers
    }
}

1

समाधान - आधार वर्ग (सार)

public abstract class Place {

String Name;
String Postcode;
String County;
String Area;

Place () {

        }

public static Place make(String Incoming) {
        if (Incoming.length() < 61) return (null);

        String Name = (Incoming.substring(4,26)).trim();
        String County = (Incoming.substring(27,48)).trim();
        String Postcode = (Incoming.substring(48,61)).trim();
        String Area = (Incoming.substring(61)).trim();

        Place created;
        if (Name.equalsIgnoreCase(Area)) {
                created = new Area(Area,County,Postcode);
        } else {
                created = new District(Name,County,Postcode,Area);
        }
        return (created);
        }

public String getName() {
        return (Name);
        }

public String getPostcode() {
        return (Postcode);
        }

public String getCounty() {
        return (County);
        }

public abstract String getArea();

}

1
कोड के रूप में सभी कोड स्वरूपण करने का प्रयास करें, और कृपया कुछ स्पष्टीकरण जोड़ें, अभी इसे शायद ही एक उत्तर माना जा सकता है।
NomeN

3
जब तक और जब तक आप अपने कोड का स्पष्टीकरण नहीं देते। आपको एक बुरा उत्तर देने वाला माना जाएगा। तो कृपया यहाँ स्पष्टीकरण दें
devsda

0

एक अमूर्त वर्ग एक ऐसा वर्ग है जिसे अमूर्त घोषित किया जाता है - इसमें अमूर्त विधियाँ शामिल हो सकती हैं या नहीं भी हो सकती हैं। अमूर्त वर्गों को तत्काल नहीं किया जा सकता है, लेकिन उन्हें उपवर्गित किया जा सकता है।

दूसरे शब्दों में, एक वर्ग जिसे अमूर्त कीवर्ड के साथ घोषित किया जाता है, जावा में सार वर्ग के रूप में जाना जाता है। इसमें अमूर्त (शरीर के बिना विधि) और गैर-अमूर्त तरीके (शरीर के साथ विधि) हो सकते हैं।

महत्वपूर्ण नोट: - सार वर्गों का उपयोग वस्तुओं को त्वरित करने के लिए नहीं किया जा सकता है, उनका उपयोग ऑब्जेक्ट संदर्भ बनाने के लिए किया जा सकता है, क्योंकि रन-टाइम पॉलिमोर्फिज्म के जावा के दृष्टिकोण को सुपरक्लास संदर्भों के उपयोग के माध्यम से लागू किया जाता है। इस प्रकार, एक अमूर्त वर्ग का संदर्भ बनाना संभव होगा, ताकि इसका उपयोग उपवर्ग वस्तु की ओर इंगित करने के लिए किया जा सके। आप इस सुविधा को नीचे दिए गए उदाहरण में देखेंगे

abstract class Bike{  
  abstract void run();  
}  

class Honda4 extends Bike{  
    void run(){
        System.out.println("running safely..");
    }  

    public static void main(String args[]){  
       Bike obj = new Honda4();  
       obj.run();  
    }  
} 

0

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


0

वह वर्ग जिसमें ठोस और गैर-ठोस दोनों विधियाँ हो सकती हैं अर्थात बिना शरीर के।

  1. बिना कार्यान्वयन के तरीकों में 'अमूर्त' कीवर्ड होना चाहिए।
  2. सार वर्ग को तत्काल नहीं किया जा सकता है।

-1

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

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