जावा एरर: डिफॉल्ट कंस्ट्रक्टर के लिए इम्प्लिक्ट सुपर कंस्ट्रक्टर अपरिभाषित है


89

मेरा कुछ सरल जावा कोड है जो इसकी संरचना में इसके समान दिखता है:

abstract public class BaseClass {
    String someString;
    public BaseClass(String someString) {
        this.someString = someString;
    }
    abstract public String getName();
}

public class ACSubClass extends BaseClass {
    public ASubClass(String someString) {
        super(someString);
    }
    public String getName() {
        return "name value for ASubClass";
    }
}

मेरे पास कुछ उपवर्ग होंगे BaseClass, प्रत्येक getName()अपने तरीके से ( टेम्पलेट विधि पैटर्न ) विधि को लागू करेंगे ।

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

जब मैं निर्माणकर्ता को उपवर्गों से हटाता हूं, तो मुझे यह संकलन-समय त्रुटि मिलती है:

Implicit super constructor BaseClass() is undefined for default constructor. Must define an explicit constructor

क्या मैं संभव करने की कोशिश कर रहा हूं?


1
कृपया, 'निरर्थक' निर्माता को छोड़ दें! यह आपके कोड की पठनीयता को बनाए रखता है और सभी आधुनिक आईडीई इसे स्वचालित रूप से बना सकते हैं, इसलिए आपको बस एक शॉर्टकट की कुंजी है।
एंड्रियास डॉक

3
एक साल बाद अपने स्वयं के प्रश्न को फिर से पढ़ना और यह मेरे साथ होता है कि मैं निर्माणकर्ता (बेस क्लास में incl) को हटा सकता था जैसे कि मैट बी का सुझाव दिया गया था, और फिर इंस्टेंसेस बनाने के लिए एक स्थिर कारखाना विधि का उपयोग करें।
जोएल

जवाबों:


146

आपको यह त्रुटि मिलती है क्योंकि एक वर्ग जिसका कोई निर्माता नहीं है, एक डिफ़ॉल्ट निर्माता है, जो तर्क-कम है और निम्नलिखित कोड के बराबर है:

public ACSubClass() {
    super();
}

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

यह शायद थोड़ा प्रति-सहज है क्योंकि आप सोच सकते हैं कि एक उपवर्ग में स्वचालित रूप से कोई रचनाकार होता है जो आधार वर्ग के पास होता है।

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


17
"यह शायद थोड़ा प्रति-सहज है क्योंकि आप सोच सकते हैं कि एक उपवर्ग में स्वचालित रूप से कोई रचनाकार होता है जो बेस क्लास के पास होता है।" +1
Mr_and_Mrs_D

2
पश्चात की खातिर, मैं भविष्य के पाठकों के लिए अपने समाधान का सुझाव दूंगा: एक नॉन-आर्ग कंस्ट्रक्टर बनाएं, BaseClassलेकिन इसे बस एक UnsupportedOperationExceptionया कुछ फेंक दें । यह सबसे अच्छा समाधान नहीं है (यह झूठा सुझाव देता है कि वर्ग एक गैर-निर्माणकर्ता का समर्थन कर सकता है), लेकिन यह सबसे अच्छा है जिसके बारे में मैं सोच सकता हूं।
JMTyler

49

उन लोगों के लिए जो इस त्रुटि के लिए Google हैं और यहां पहुंचे: इसे प्राप्त करने का एक और कारण हो सकता है। जब आप प्रोजेक्ट सेटअप - सिस्टम कॉन्फ़िगरेशन मिसमैच करते हैं तो ग्रहण यह त्रुटि देता है।

उदाहरण के लिए, यदि आप ग्रहण करने के लिए जावा 1.7 परियोजना को आयात करते हैं और आपके पास 1.7 सही ढंग से सेट नहीं है, तो आपको यह त्रुटि मिलेगी। तब आप या तो जा सकते हैं Project - Preference - Java - Compilerऔर switch to 1.6 or earlier; या Window - Preferences - Java - Installed JREsअपने JRE 1.7 संस्थापन को जोड़ें या ठीक करें।


2
बस ग्रहण में कोई स्पष्ट कारण के लिए यह त्रुटि मिली। फिर मैंने कार्यक्षेत्र (मेनू प्रोजेक्ट -> क्लीन ...) को साफ किया और यह चला गया।
erickrf

7

यह संभव है लेकिन आपके पास ऐसा नहीं है।

आपको आधार वर्ग में एक नो-आर्ग्स कंस्ट्रक्टर को जोड़ना होगा और वह यह है!

public abstract class A {
    private String name;
    public A(){
        this.name = getName();
    }
    public abstract String getName();


    public String toString(){
        return "simple class name: " + this.getClass().getSimpleName() + " name:\"" + this.name + "\"";
    }
}
class B extends A {
    public String getName(){
        return "my name is B";
    }
    public static void main( String [] args ) {
        System.out.println( new C() );
    }
}
class C extends A {
    public String getName() {
        return "Zee";
    }
}

जब आप एक क्लास में कंस्ट्रक्टर (कोई भी) नहीं जोड़ते हैं, तो कंपाइलर आपके लिए डिफॉल्ट नो arg कंस्ट्रक्टर को जोड़ देता है।

जब अवशिष्ट कोई आर्ग सुपर () को कहता है; और जब से आपके पास यह सुपर क्लास में नहीं है, तो आपको वह त्रुटि संदेश मिलता है।

इस सवाल के बारे में यह स्व।

अब, उत्तर का विस्तार करते हुए:

क्या आप जानते हैं कि एक अलग मूल्य (डेटा) को निर्दिष्ट करने के लिए उपवर्ग (व्यवहार) बनाने से कोई मतलब नहीं है ?? !!! मुझे उम्मीद है कि तुम करोगे।

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

तो आपको इसकी आवश्यकता नहीं है:

MyClass a = new A("A");
MyClass b = new B("B");
MyClass c = new C("C");
MyClass d = new D("D");

या

MyClass a = new A(); // internally setting "A" "B", "C" etc.
MyClass b = new B();
MyClass c = new C();
MyClass d = new D();

जब आप यह लिख सकते हैं:

MyClass a = new MyClass("A");
MyClass b = new MyClass("B");
MyClass c = new MyClass("C");
MyClass d = new MyClass("D");

अगर मुझे बेसक्लास कंस्ट्रक्टर के विधि हस्ताक्षर को बदलना था, तो मुझे सभी उपवर्गों को बदलना होगा।

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

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

 public interface NameAware {
     public String getName();
 }



 class A implements NameAware ...
 class B implements NameAware ...
 class C ... etc. 

यहाँ B और C को A से विरासत में मिला है जो उनके बीच एक बहुत ही उच्च युग्मन बनाया होगा, इंटरफेस के उपयोग से युग्मन कम हो जाता है, यदि A निर्णय करता है कि यह "NameAware" नहीं होगा तो अन्य कक्षाएं नहीं टूटेंगी।

बेशक, यदि आप व्यवहार का पुन: उपयोग करना चाहते हैं तो यह काम नहीं करेगा।


2
हां, इसके अलावा आप अब यह सुनिश्चित नहीं कर सकते हैं कि आपके उदाहरण ठीक से आरंभीकृत हैं (जैसे इस विशेष मामले में नाम हैं)
ChssPly76

@ ChssPly76: हां, लेकिन ऐसा शायद इसलिए है क्योंकि विरासत का खराब तरीके से इस्तेमाल किया जा रहा है। मैंने इसे कवर करने के लिए अपने उत्तर का विस्तार किया।
ऑस्कररिज़

4

JRE सेट नहीं होने पर आपको यह त्रुटि भी हो सकती है। यदि हां, तो अपने प्रोजेक्ट में JRE सिस्टम लाइब्रेरी को जोड़ने का प्रयास करें।

ग्रहण आईडीई के तहत:

  1. ओपन मेनू प्रोजेक्ट -> गुण , या पैकेज एक्सप्लोरर में अपनी परियोजना पर राइट-क्लिक करें और गुण चुनें (Alt + Windows पर दर्ज करें, कमांड + I पर क्लिक करें)
  2. जावा बिल्ड पाथ पर फिर लाइब्रेरी टैब पर क्लिक करें
  3. चुनें Modulepath या क्लासपाथ और प्रेस लाइब्रेरी जोड़ें ... बटन
  4. JRE सिस्टम लाइब्रेरी का चयन करें और फिर अगला क्लिक करें
  5. रखने कार्यस्थान डिफ़ॉल्ट JRE चयनित (आप भी एक और विकल्प ले जा सकते हैं) और क्लिक समाप्त
  6. अंत में लागू करें और बंद करें दबाएं ।

2

एक अन्य तरीका कॉल सुपर () आवश्यक तर्क के साथ व्युत्पन्न वर्ग निर्माता में पहले बयान के रूप में है।

public class Sup {
    public Sup(String s) { ...}
}

public class Sub extends Sup {
    public Sub() { super("hello"); .. }
}

0

यदि आपने सुपर क्लास कंस्ट्रक्टर को सबक्लास कंस्ट्रक्टर में पहले स्टेटमेंट के रूप में कॉल नहीं किया है तो ग्रहण यह त्रुटि देगा।


0

नेक्रोपोस्टिंग के लिए क्षमा करें, लेकिन आज ही इस समस्या का सामना किया। इस समस्या से जूझ रहे हर व्यक्ति के लिए - उसके संभावित कारणों में से एक - आप superविधि की पहली पंक्ति पर कॉल नहीं करते हैं । दूसरी, तीसरी और अन्य लाइनें इस त्रुटि को आग लगाती हैं। सुपर का कॉल आपकी विधि में बहुत पहले कॉल होना चाहिए। इस मामले में सब कुछ ठीक है।


0

मैंने उपरोक्त समस्या का समाधान इस प्रकार किया है:

  1. प्रोजेक्ट पर क्लिक करें।
  2. गुणों पर क्लिक करें> जावा बिल्ड पाथ> लाइब्रेरी> जेआरई सिस्टम लाइब्रेरी> संपादित करें
  3. डिफ़ॉल्ट सिस्टम JRE और फिनिश चुनें
  4. लागू करें और बंद करें।

-1

आप बेस क्लास (जैसा कि नीचे दिखाया गया है) में एक तर्कहीन कंस्ट्रक्टर को जोड़कर इस त्रुटि को हल कर सकते हैं।

चीयर्स।

 abstract public class BaseClass {
        // ADD AN ARGUMENTLESS CONSTRUCTOR TO THE BASE CLASS
        public BaseClass(){
        }

        String someString;
        public BaseClass(String someString) {
            this.someString = someString;
        }
        abstract public String getName();
    }

public class ACSubClass extends BaseClass {
    public ASubClass(String someString) {
        super(someString);
    }
    public String getName() {
        return "name value for ASubClass";
    }
}

इससे अमान्य ऑब्जेक्ट (बिना someString) वाले सेट का निर्माण करना आसान हो जाता है और इसलिए पूरी तरह से निर्माता के उद्देश्य को हरा देता है।
रॉबर्ट

-1

मेरे पास यह त्रुटि थी और इसे विधि के पास से एक थ्रो अपवाद को हटाकर एक कोशिश / कैच ब्लॉक में लाया गया था

उदाहरण के लिए: FROM:

public static HashMap<String, String> getMap() throws SQLException
{

}

सेवा:

public static Hashmap<String,String> getMap()
{
  try{

  }catch(SQLException)
  { 
  }
}

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