Java 컨스트럭터 상속
왜 자바 컨스트럭터가 상속되지 않는지 궁금해요.이런 수업이 있을 때 있잖아요.
public class Super {
public Super(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
this.serviceA = serviceA;
//etc
}
}
에 중 from에서 때Super
되어 있지 합니다.javava는 기본 컨스트럭터가 정의되어 있지 않습니다.츠키다
public class Son extends Super{
public Son(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
super(serviceA,serviceB,serviceC);
}
}
이 코드는 반복적이며, 건조하고 쓸모없는(IMHO) 것이 아닙니다.그러면 다시 의문이 생깁니다.
java가 생성자 상속을 지원하지 않는 이유는 무엇입니까?이 상속을 허용하지 않는 것이 무슨 이득이 있나요?
컨스트럭터를 상속받았다고 가정하면...모든 클래스는 결국 객체에서 생성되므로 모든 클래스는 파라미터가 없는 생성자로 끝납니다.그것은 좋은 생각이 아니에요.정확히 무엇을 예상하십니까?
FileInputStream stream = new FileInputStream();
어떻게 해야 할까요?
일반적으로 사용되는 "패스스루" 컨스트럭터를 쉽게 만들 수 있는 방법이 있을 수 있지만 디폴트로는 만들 수 없다고 생각합니다.서브클래스를 구축하는 데 필요한 파라미터는 슈퍼클래스에 필요한 파라미터와 다른 경우가 많습니다.
Super에서 상속받으면 실제로 다음과 같은 일이 발생합니다.
public class Son extends Super{
// If you dont declare a constructor of any type, adefault one will appear.
public Son(){
// If you dont call any other constructor in the first line a call to super() will be placed instead.
super();
}
}
그렇기 때문에 독자적인 컨스트럭터에게 전화해야 합니다.Super'에는 기본값이 없습니다.
Java가 컨스트럭터 상속을 지원하지 않는 이유를 추측해 보겠습니다.아마 컨스트럭터는 구체적인 인스턴스에 대해서만 의미가 있기 때문일 것입니다.또, (다형성에 의해) 어떻게 정의되어 있는지 모르는 경우에는, 어떤 인스턴스의 작성은 할 수 없습니다.
서브클래스 오브젝트를 작성하는 방법은 슈퍼클래스가 작성되는 방법과 다를 수 있습니다.서브클래스의 클라이언트가 슈퍼클래스에서 사용할 수 있는 특정 컨스트럭터를 호출할 수 없게 하는 경우가 있습니다.
어리석은 예:
class Super {
protected final Number value;
public Super(Number value){
this.value = value;
}
}
class Sub {
public Sub(){ super(Integer.valueOf(0)); }
void doSomeStuff(){
// We know this.value is an Integer, so it's safe to cast.
doSomethingWithAnInteger((Integer)this.value);
}
}
// Client code:
Sub s = new Sub(Long.valueOf(666L)): // Devilish invocation of Super constructor!
s.doSomeStuff(); // throws ClassCastException
또는 보다 심플하게:
class Super {
private final String msg;
Super(String msg){
if (msg == null) throw new NullPointerException();
this.msg = msg;
}
}
class Sub {
private final String detail;
Sub(String msg, String detail){
super(msg);
if (detail == null) throw new NullPointerException();
this.detail = detail;
}
void print(){
// detail is never null, so this method won't fail
System.out.println(detail.concat(": ").concat(msg));
}
}
// Client code:
Sub s = new Sub("message"); // Calling Super constructor - detail is never initialized!
s.print(); // throws NullPointerException
이 예에서 "I want to inherit these constructors" 또는 "I want to inherit these constructors"를 선언하고, 슈퍼클래스에 새로운 컨스트럭터를 추가할 경우에 대비하여 기본 컨스트럭터 상속 프리퍼런스를 지정해야 합니다.혹은 슈퍼클래스의 컨스트럭터들을 「재설정」하고 싶다면, 그것을 반복하도록 요구할 수도 있습니다.그것은 거의 틀림없이 더 확실한 방법입니다.
컨스트럭터는 구현 세부사항이기 때문에 인터페이스/슈퍼클래스 사용자가 실제로 호출할 수 있는 것은 아닙니다.인스턴스를 얻을 때는 이미 구성된 상태이고 반대로 개체를 생성할 때는 현재 할당된 변수가 정의상 없습니다.
모든 서브클래스에 강제로 상속된 컨스트럭터를 갖게 하는 것이 무엇을 의미하는지 생각해 보십시오.저는 단지 부모라는 이유만으로 학급이 특정 수의 주장을 가진 생성자를 "마술처럼" 가지고 있는 것보다 변수를 직접 전달하는 것이 더 명확하다고 주장합니다.
츠키다
이미 생성된 클래스를 처리할 때 오브젝트의 선언된 유형 또는 오브젝트의 서브클래스를 처리할 수 있습니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
: 특정 유형)으로 호출됩니다.new String()
는 이에 아무런 이 없습니다 가상 서브클래스는 여기에 관여하지 않습니다.
David의 답은 정확하다.저는 당신이 당신의 디자인이 엉망이라는 것을 신으로부터 징조를 받고 있다는 것을 덧붙이고 싶습니다.그리고 "Son"은 "Super"의 하위 클래스가 되어서는 안 되지만, 대신 Super는 Son이 제공하는 기능을 일종의 전략으로 가장 잘 표현함으로써 구현 세부 사항을 가지고 있습니다.
편집: Jon Sket의 답변은 매우 놀랍습니다.
(슈퍼) 클래스는 구성 방법을 완전히 제어할 수 있어야 합니다.프로그래머가 기본(args 없음) 컨스트럭터를 클래스 계약의 일부로 제공하는 것이 타당하지 않다고 판단했을 경우 컴파일러는 이를 제공하지 않아야 합니다.
기본적으로는 단순히 슈퍼라고 부를 수 있는 의미에서는 디폴트로 발생한 경우 다른 사람이 언급한 이유로 인해 오류가 발생하기 쉽다는 의미입니다.컴파일러는 언제가 적절하고 언제가 적절하지 않은지 예측할 수 없습니다.
컴파일러의 역할은 복잡성과 의도하지 않은 부작용의 위험을 줄이면서 최대한의 유연성을 제공하는 것입니다.
서브클래스가 컨스트럭터를 계승하는 언어는 모릅니다(그렇다면 저는 프로그래밍 폴리글롯은 잘 모릅니다).
다음은 C#에 관한 동일한 질문에 대한 설명입니다.일반적인 의견 일치는 그것이 언어를 복잡하게 만들고, 기저 계급의 변화에 나쁜 부작용을 일으킬 수 있는 가능성을 도입할 것이며, 일반적으로 좋은 디자인에는 필요하지 않을 것이라는 것이다.
파생 클래스는 기본 클래스와 동일한 클래스가 아니며 파생 클래스를 구성할 때 기본 클래스의 멤버가 초기화되는지 여부에 상관하지 않을 수 있습니다.그것은 컴파일러가 아니라 프로그래머가 내린 결정입니다.
언급URL : https://stackoverflow.com/questions/1644317/java-constructor-inheritance
'programing' 카테고리의 다른 글
Vuex 스토어 내 2차원 배열에서 항목 업데이트 (0) | 2022.06.10 |
---|---|
Vue JS가 v-for에서 데이터 전송 버튼 클릭 (0) | 2022.06.10 |
vuex 모듈에도 네임스페이스가 필요합니까? (0) | 2022.06.10 |
그래들과의 복수 프로젝트 테스트 의존성 (0) | 2022.06.10 |
uint_fast32_t보다 uint32_t가 선호되지 않는 이유는 무엇입니까? (0) | 2022.06.10 |