2011-01-25 5 views
32

abstract 클래스의 생성자를 직접 호출하여 개체를 만들 수 없습니다. abstract 클래스의 생성자는 파생 클래스에서만 호출 할 수 있습니다. 그러므로 인 것처럼 보입니다. 추상 클래스의 생성자는 protected이거나 package-private이어야합니다 (패키지 내의 파생 클래스에 생성자 사용을 제한하는 예외적 인 경우는 후자). 그러나 자바는 abstract 클래스의 생성자가 public이되도록 허용합니다.추상 클래스의 public 생성자에 대한 좋은 이유가 있습니까

유용public보다는 protected 또는 패키지 - 개인이 될하는 abstract 클래스의 생성자를 선언하는 것입니다있는 어떤 상황이 있습니까?

이것은 "Abstract class constructor access modifier"질문의 꽤 중복되지 않습니다 : 명확하게 public을 할 생성자를 선언 할 수 있습니다; 나는 어떤 좋은 좋은 이유가 있는지 알고 싶습니다. 거기에는없는 것처럼 보입니다. 나는 그것이 C# has a similar peculiarity임을 안다.

+0

생성자는 개체의 "생성"과 아무 관련이 없습니다. 이것은 객체를 "생성"하는 동안 호출되는 메서드 일뿐입니다. 따라서 Abstract 클래스는 Abstract 클래스의 인스턴스를 생성하는 동안 (Subclass를 통해) 호출되는 public 생성자를 가질 수 있으며, 생성자 메소드에서는 멤버 변수를 초기화하는 코드를 작성합니다. http://stackoverflow.com/questions/260666/can-an-abstract-class-have-a-constructor?lq=1 –

+1

생성자는 생성자 체인에서 사용할 수있는'private' 일 수도 있습니다. –

답변

16

대답은 자바에 대해 동일합니다 :

추상 클래스의 public 생성자에 대한 이유가 없습니다. 필자는 컴파일러가 불평하지 않는 이유는 단순히 public이나 protected 일지라도 문제가되지 않기 때문에 시간을 낭비하지 않고 간단하다고 가정합니다. (source)

직접 하위 클래스 이외의 것으로부터 추상 클래스의 생성자를 호출 할 수 없습니다.

추상 클래스의 생성자에 대한 액세스 한정자에 특별한 규칙을 추가한다고해서 해당 언어에 유용한 것이 추가되지는 않습니다. 이 규칙에서 예외처럼 보이는


일 - 추상 클래스는 기본 생성자를 정의하는 경우, 서브 클래스가 생성자를 구현하지 않습니다 :이 법률이다 :

public abstract class A { 
    public A() {} 
} 

public class B extends A {} 

따라서 new B()을 호출하여 B을 만들 수 있습니다. 그러나 은 여전히 ​​이며 A이 아닌 B을 생성합니다. 그리고 다시, A의 생성자가 public이거나 protected인지 여부는 중요하지 않습니다. 그것은 단지 개인되지해야하지만, 컴파일러는

-8

당신은 할 수 있습니다 ...

는 실제로 우리가 간단한 super() 전화를하지 B 상에 "보이지 않는"공공의 기본 생성자를 호출 ... 통지하고 불평 할 것이다 하위 클래스의 생성자에서 정의하지 않으면 공용 생성자입니다. 예를

작동하지 않습니다 공개하지 않은 경우 생성자가 호출됩니다 상위 클래스의 생성자를 정의되지 않은 경우
abstract class Animal { 
    String name; 
    public void Animal(String name) { 
     this.name = name; 
    } 
} 


class Cat extends Animal{ 
    public String sayMayName() { 
     return this.name; 
    } 
} 

myCat = new Cat("tester"); 

name = myCat.sayMyName(); 

. 이것은 내가 더 우아하게 공장 패턴으로 이루어 졌다고 생각하지만, 실제로 PHP에서 그것을 사용하고 잘 동작합니다.

+3

Java에서는 작동하지 않습니다. 또한 반환 유형 ('void')을 지정하기 때문에'Animal' 클래스에 생성자를 정의하지 않습니다. –

+2

'Animal'이 (기본값이 아닌) 생성자를 가지고 있기 때문에 ('public void Animal (String name)'이 생성자가 아닙니다.) –

+0

이것은 오직 작동 할 것입니다 인수가없는 생성자와 함께. 시도해보십시오. 코드가 컴파일되지 않습니다. 그러나 암시 적 기본 생성자는 수퍼 클래스 생성자와 관계없이 항상 클래스 자체의 가시성을 갖습니다. – biziclop

-7

나를 이단이라고 부르지 만 ... 나는 추상 클래스의 생성자를 적어도 한 번 보았다.

즉 : 생성자 매개 변수의 모양을 지정하는 것입니다.

추상 생성자를 지정하여 클래스를 추상화합니다. 파생 클래스는 추상적 상태를 잃을 특정 서명으로이 생성자를 구현해야합니다.

필수 생성자 서명을 지정하는 다른 방법은 없습니다 (도움이된다면 도와주세요).

+3

생성자를 protected로 설정하면 "생성자 매개 변수의 모양을 지정"할 수 있습니다. – Raedwald

+0

true이지만 그렇게하면 파생 클래스가 super()를 호출하거나 발생할 수있는 init 단계가 누락 될 위험이 있습니다. 초록은 이것이 서명 일 뿐이며 구현이 아니라는 것을 분명히합니다. - 인터페이스가 생성자 시그니처를 지정하도록 허용 된 경우 가장 좋습니다. 그러나 그들이하지 않기 때문에, 나는 추상적 인 수업을 다음으로 가장 좋은 것으로 생각한다. – foo

+3

'슈퍼'를 부르는 것을 피할 수는 없습니다. 명시 적으로 호출하지 않으면 암시 적으로 호출됩니다. – Raedwald

0

가시성은 특정 가시성 수준을 제외하도록 선택한 경우 javadoc에 표시된 내용에도 영향을줍니다. 달리 중요하지 않으므로 추상 클래스의 공용 생성자에 대한 사용법이 될 수 있습니다.

생성자를 제공하지 않으면 클래스가 public이면 기본 생성자가 public입니다. 가장 쉬운 옵션은 보호 된 생성자를 강요하는 것이 아니라이를 허용하는 것입니다.

그런 의미에서 역 의문은 분명합니다. 왜 그들은 추상적 클래스에서 보호 된 생성자를 강제로 사용하지 않았습니까? public 생성자는 아무 것도 변경하지 않으므로 시간이 걸리고 복잡성이 추가됩니다.

관련 문제