해결된 질문
작성
·
129
0
해당 내용 중
Parent parent = new Child(3); // 6
이 실행되면
이후 3 -> 1 순서로 진행된다고 설명해주셨는데,
만일 아래코드와 같이 super를 명시적으로 호출하지 않고, 파라미터도 동일하다면 순서가 1 -> 3의 순서로 진행되는 것일까요??
class Parent {
int x;
Parent(int x) { // 1
this.x = x;
}
...
}
class Child extends Parent {
int x;
Child(int x) { // 3
this.x = x;
}
...
}
...
만일 위 내용이 맞다면, 아래와 같이, 같은 파라미터의 생성자이면서 super를 명시적으로 작성했을 경우에는 순서가 어떻게 되는지도 궁금합니다.
(child의 생성자 내부 코드라인에 super가 존재해서 child의 생성자 호출이 우선인 것인지, 혹은 super가 명시적으로 없어도 child의 생성자 호출이 우선인것인지가 헷깔립니다ㅜ)
class Parent {
int x;
Parent(int x) { // 1
this.x = x;
}
...
}
class Child extends Parent {
int x;
Child(int x) { // 3
super(x + 1);
this.x = x;
}
...
}
...
답변 2
0
답변 요약: 주신 코드가 오류가 발생하는 코드이기 때문에 출제되지 않습니다.
우선 이 문제, 출제 당시에도 여러 네이버 카페에서 논란이 많았습니다.
일단 출제된 코드 자체는 순서를 명확하게 말 할 수 있습니다. 자식 생성자에서 명확하게 부모의 생성자를 지정했기 때문입니다.
여기서는 자식 생성자에서 명시적으로 부모의 생성자를 호출하기 때문에 자식 생성자에 가지 않고서는 부모의 생성자를 뭘 호출할지 모릅니다.
만약에 논란이 될 수 있다면, 다른 코드가 출제되는 경우에는 이상해집니다.
부모의 기본 생성자가 호출될 때는 어떻게 실행 순서를 명시해야하느냐 입니다.
(자식 생성자에서 명시적으로 호출하지 않아서 부모 기본 생성자를 호출해야하는 상황인 경우에 자식 생성자를 먼저 간 거로 봐야하는가 아니면 부모 생성자를 먼저 본 것으로 해야하는가.)
Java를 좀 더 깊게 공부하시게 되면 알게 되는데 Java는 운영체제별로 해석해주는 JVM이라는 가상머신이 있습니다. 이 머신이 자바 바이트 코드를 해석합니다.
문제는 우리는 Java 언어를 해석하는데 정확한 순서를 알려면 자바 바이트 코드를 알아야 합니다.
근데 정보처리기사 실기는 그정도를 요구하지 않습니다. Java 개발자도 그정도까지 깊게 들여다보지 않고요.
그래서 제가 무슨 말을 하고 싶은거냐면,
저런 문제는 나오지 않습니다.
그것과 상관없이 질문 주신 코드는 오류 납니다.
부모에는 기본 생성자가 없는데, 명시적으로 파라미터 있는 생성자 호출(super(x+1, x))을 삭제해버리셨기 때문에 그렇습니다. (아래 코드로 동작시켜 보시면 오류 확인 가능합니다.)
public class Main {
public static void main(String[] args) { // 5
Parent parent = new Child(3); // 6
System.out.println(parent.getA()); // 7
}
}
class Parent {
int x, y;
Parent(int x) { // 1
this.x = x;
}
int getA() { // 2
return x * y;
}
}
class Child extends Parent {
int x;
Child(int x) { // 3
this.x = x;
}
int getA(int n) { // 4
return super.getA() + n;
}
}
질문 주신 코드도 오류가 나서 출제가 안되기도 하지만,
순서를 보기에 애매한 것들은 모두 해석 순서에 나오지 않습니다.
자식 생성자를 가봐야 어떤 부모 생성자를 갈 지 알 수 있는데,
실제로 출력되는 것은 부모 생성자부터 출력되기 때문입니다.
"출력되는 순서대로 작성하라" 라고 문제가 나오면 또 모르겠네요.
추가 질문이 있으신 경우에는 대댓글로 부탁드립니다!
0
안녕하세요, 인프런 AI 인턴입니다. Sungyeop Choo님.
자바에서의 상속과 생성자 호출 순서는 학습자분들께 자주 궁금증을 일으키는 주제입니다. 질문하신 내용에서 두 가지 시나리오에 대해 설명드리겠습니다.
class Parent {
int x;
Parent(int x) { // 1
this.x = x;
}
}
class Child extends Parent {
int x;
Child(int x) { // 3
this.x = x;
}
}
Child
클래스의 생성자가 호출될 때 암시적으로 부모 클래스의 기본 생성자 호출을 시도합니다. 그러나, Parent
클래스에 기본 생성자가 없기 때문에 컴파일 오류가 발생합니다.class Parent {
int x;
Parent(int x) { // 1
this.x = x;
}
}
class Child extends Parent {
int x;
Child(int x) { // 3
super(x + 1); // 명시적으로 부모 생성자 호출
this.x = x;
}
}
Child
클래스의 생성자가 호출될 때, super(x + 1);
를 통해 부모 클래스의 생성자를 명시적으로 호출합니다. 따라서 실제 실행 순서는 부모 생성자가 먼저 호출됩니다.3(실제 호출) -> 1 -> 3(할당)
이렇게 진행됩니다.결론적으로, super()가 명시적으로 있을 경우 부모 생성자 호출이 명확하게 먼저 이루어집니다. 일반적으로 자바에서는 자식 클래스의 생성자가 자신의 부모 클래스의 특정 생성자를 호출하기 전까지는 객체화 과정이 완료되지 않기 때문에, super()가 항상 우선하여 실행되는 것이 맞습니다.
추가적인 참고를 원하신다면 이에 관한 기본 개념에 대해 다음과 같은 링크들을 추천드립니다:
- 자바의 생성자 호출 순서에 대한 설명
- 자바 상속과 관련된 디테일
저는 질문자님의 이해를 돕고자 지식공유자의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.