Java 오류 : 암시 적 슈퍼 생성자가 기본 생성자에 대해 정의되지 않았습니다.


89

구조에서 다음과 유사한 간단한 Java 코드가 있습니다.

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
'중복'생성자를 남겨주세요! 코드의 가독성을 유지하고 모든 최신 IDE에서 자동으로 생성 할 수 있으므로 단축키를 입력하기 만하면됩니다.
Andreas Dolk

3
1 년 후 내 자신의 질문을 다시 읽으면 matt b가 제안한 것처럼 생성자 (기본 클래스에 포함)를 제거한 다음 정적 팩토리 메서드를 사용하여 인스턴스를 빌드 할 수있었습니다.
Joel

답변:


146

생성자가없는 클래스에는 인수가없고 다음 코드와 동일한 기본 생성자 가 있기 때문에이 오류가 발생 합니다.

public ACSubClass() {
    super();
}

그러나 BaseClass가 생성자를 선언하기 때문에 (따라서 컴파일러가 제공 super();하는 인수가없는 기본 생성자가 없기 때문에 ) 이것은 불법입니다. 인수가없는 생성자가 없기 때문에 BaseClass를 확장하는 클래스를 호출 할 수 없습니다. BaseClass에서.

하위 클래스가 기본 클래스에있는 생성자를 자동으로 갖는다 고 생각할 수 있기 때문에 이것은 약간 직관적이지 않습니다.

이 문제를 해결하는 가장 간단한 방법은 기본 클래스가 생성자를 선언하지 않거나 (따라서 인수가없는 기본 생성자를 가짐) 선언 된 인수가없는 생성자를 (자체적으로 또는 다른 생성자와 함께) 갖는 것입니다. 그러나 종종이 접근 방식은 적용 할 수 없습니다. 클래스의 합법적 인 인스턴스를 생성하기 위해 생성자에 전달되는 인수가 필요하기 때문입니다.


17
"이것은 서브 클래스가 기본 클래스에있는 생성자를 자동으로 포함한다고 생각할 수 있기 때문에 다소 직관적이지 않습니다." +1
Mr_and_Mrs_D 2013-04-03

2
후손을 위해 미래의 독자를 위해 내 솔루션을 제안 할 것입니다. 인수가없는 생성자를 생성 BaseClass하되 단순히 UnsupportedOperationException또는 무언가 를 던지도록 만드십시오 . 이것이 최선의 해결책은 아니지만 (이 클래스가 인수가없는 생성자를 지원할 수 있다고 잘못 제안 함), 제가 생각할 수있는 최선의 방법입니다.
JMTyler

49

Google에서이 오류를보고 여기에 도착한 사용자를 위해 : 오류를 수신하는 또 다른 이유가있을 수 있습니다. 프로젝트 설정이있는 경우 Eclipse에서이 오류가 발생합니다. 시스템 구성이 일치하지 않습니다.

예를 들어 Java 1.7 프로젝트를 Eclipse로 가져오고 1.7을 올바르게 설정하지 않은 경우이 오류가 발생합니다. 그런 다음 Project - Preference - Java - Compiler및 로 이동할 수 있습니다 switch to 1.6 or earlier. 또는 Window - Preferences - Java - Installed JREsJRE 1.7 설치 로 이동하여 추가 / 수정하십시오.


2
Eclipse에서 명백한 이유 없이이 오류가 발생했습니다. 그런 다음 작업 공간을 정리했습니다 (메뉴 프로젝트-> 정리 ...).
erickrf 2014

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";
    }
}

클래스에 생성자 (any)를 추가하지 않으면 컴파일러가 기본값 인 인수 없음 생성자를 추가합니다.

기본적으로 arg가 super ()를 호출하지 않을 때; 수퍼 클래스에 없기 때문에 오류 메시지가 표시됩니다.

그 자체가 질문에 관한 것입니다.

이제 대답을 확장하십시오.

다른 값 (data)을 지정하기 위해 하위 클래스 (behavior)를 만드는 것이 의미가 없다는 것을 알고 있습니까 ?? !!! 니가하길 바래.

변경되는 유일한 것이 "이름"이면 매개 변수화 된 단일 클래스로 충분합니다!

따라서 다음이 필요하지 않습니다.

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");

BaseClass 생성자의 메서드 시그니처를 변경하려면 모든 하위 클래스를 변경해야합니다.

그렇기 때문에 상속이 OO 시스템에서는 바람직하지 않은 HIGH 결합을 생성하는 아티팩트입니다. 피하고 아마도 구성으로 대체해야합니다.

정말 하위 클래스로 필요한지 생각해보십시오. 그렇기 때문에 인터페이스가 자주 사용되는 것을 볼 수 있습니다.

 public interface NameAware {
     public String getName();
 }



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

여기서 B와 C는 인터페이스를 사용하여 결합이 감소 된 A에서 상속되었을 수 있습니다. A는 인터페이스를 사용하여 결합이 감소합니다.

물론 동작을 재사용하려면 작동하지 않습니다.


2
예, 더 이상 인스턴스가 제대로 초기화되었는지 확인할 수 없다는 점을 제외하고 (예 :이 특정 경우에는 이름이 있음)
ChssPly76

@ ChssPly76 : 예,하지만 상속이 제대로 사용되지 않기 때문일 수 있습니다. 나는 그것을 다루기 위해 내 대답을 확장했습니다.
OscarRyz

4

JRE가 설정되지 않은 경우에도이 오류가 발생할 수 있습니다. 그렇다면 프로젝트에 JRE 시스템 라이브러리 를 추가해보십시오 .

Eclipse IDE에서 :

  1. 메뉴 열기 프로젝트 -> 속성패키지 탐색기 에서 프로젝트를 마우스 오른쪽 버튼으로 클릭 하고 속성 (Windows의 경우 Alt + Enter, Mac의 경우 Command + I)을 선택합니다.
  2. Java Build Path 를 클릭 한 다음 Libraries 탭을 클릭합니다.
  3. 고르다 Modulepath 또는 Classpath를 하고 Add Library ... 버튼을 누릅니다.
  4. 고르다 JRE 시스템 라이브러리는 다음을 클릭합니다 다음을
  5. 유지 작업 공간 기본 JRE를 선택 (당신은 또한 다른 옵션을 취할 수)을 클릭 마침을
  6. 마지막으로 적용 및 닫기를 누릅니다 .

2

또 다른 방법은 파생 클래스 생성자에서 첫 번째 문으로 필요한 인수를 사용하여 super ()를 호출하는 것입니다.

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

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

0

서브 클래스 생성자에서 첫 번째 명령문으로 수퍼 클래스 생성자를 호출하지 않으면 Eclipse에서이 오류를 표시합니다.


0

necroposting에 대해 죄송하지만 오늘 바로이 문제에 직면했습니다. 이 문제에 직면 한 모든 사람들에게-가능한 이유 중 하나-당신 super은 메소드의 첫 번째 줄에서 호출하지 않습니다 . 두 번째, 세 번째 및 다른 줄에서이 오류가 발생합니다. 슈퍼 호출은 메서드에서 가장 먼저 호출해야합니다. 이 경우 모든 것이 잘됩니다.


0

위의 문제를 다음과 같이 해결했습니다.

  1. 프로젝트를 클릭하십시오.
  2. 속성> Java 빌드 경로> 라이브러리> JRE 시스템 라이브러리> 편집을 클릭하십시오.
  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로서의 목적을 완전히 무효화합니다 .
Robert

-1

이 오류가 발생하여 메서드 옆에서 try / catch 블록으로 throw 된 예외를 제거하여 수정했습니다.

예 : FROM :

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

}

에:

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

  }catch(SQLException)
  { 
  }
}

이 대답은 누락 된 생성자에 대한 컴파일러 오류와 관련이 없습니다.
로버트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.