해결된 질문
작성
·
108
·
수정됨
0
안녕하세요.
정확하게 어떤 부분이라기 보다는 제가 부모의 기본 생성자 호출 관련하여 정확하게 이해를 하지 못해 질문드립니다.
자식이 태어날때엔 부모의 기본생성자를 호출하는 조건이 무조건인건지 궁금합니다.
태어난다는 기준도 public 이후에 자식이 호출되는 순간이 태어나는건지.. 제가 이해를 잘 못하다 보니 혹시 추가 설명을 해주실 수 있을까요?
정리하면 Java에서
자식이 태어난다는 기준이 public 후 생성자로 기능을 시작할 때 태어나는 것인지.
super(매개변수)를 통해 부모의 매개변수를 직접 명시하여 호출하지 않으면 자식이 태어나면서 무조건 부모의 기본생성자를 호출하는건지.'
위의 두가지 질문드립니다.
답변 2
0
안녕하세요, 상속 전체적으로 설명 한 번 드리겠습니다.
먼저 2줄로 요약하자면 이렇습니다.
부모에 기본 생성자가 있을 경우: 자식 클래스에서 부모 생성자를 명시적으로 호출하지 않으면 기본 생성자가 자동으로 호출됨. 없으면 그냥 무시하고 넘어가자.
부모에 매개변수가 있는 생성자만 있을 경우: 자식 클래스에서 반드시 super()
를 사용하여 부모 생성자를 명시적으로 호출해야 함.
Java 언어를 깊게 배우면 알게 되는 것인데, 알면 오히려 더 헷갈리는 것 중에서
"부모에 생성자가 없는데도 불구하고 기본생성자가 호출된다." 입니다. 생성자가 아예 없으면, Java 프로그램이 실행되는 과정에서 빈 내용의 생성자()가 호출된다고 생각하고 넘어가시면 됩니다.
class Parent {
// 기본 생성자
public Parent() {
System.out.println("Parent 클래스의 기본 생성자");
}
}
class Child extends Parent {
// 기본 생성자
public Child() {
// 명시적으로 부모 생성자를 호출하지 않음 -> 자동으로 Parent() 호출
System.out.println("Child 클래스의 기본 생성자");
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child(); // Child 객체 생성
}
}
출력값:
Parent 클래스의 기본 생성자
Child 클래스의 기본 생성자
이 경우에는 Child 클래스가 태어나면, 부모의 생성자를 먼저 실행시킨 후에 부모가 가지고 있는 변수와 메서드를 모두 가져와서 자신에게 세팅합니다. 다만, 개발자가 Child 클래스 내에 부모의 메서드와 똑같은 이름으로 작성한 메서드가 있으면 오버라이딩(재정의)를 합니다.
class Parent {
// 매개변수가 있는 생성자만 존재
public Parent(String message) {
System.out.println("Parent 클래스의 생성자: " + message);
}
}
class Child extends Parent {
// 자식 클래스의 생성자
public Child() {
// 부모 클래스의 매개변수가 있는 생성자를 명시적으로 호출
super("안녕하세요, Parent입니다.");
System.out.println("Child 클래스의 생성자");
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child(); // Child 객체 생성
}
}
출력값:
Parent 클래스의 생성자: 안녕하세요, Parent입니다.
Child 클래스의 생성자
이 경우에는 super로 직접 자식 생성자에서 명시했고, 그래서 부모의 생성자 중에서 문자열 1개가 들어가는 생성자를 호출한 것입니다. 이미 생성자가 하나 호출되고 끝났죠? (객체 생성 완료)
그러면 기본 생성자는 호출되지 않습니다.
하지만 만약에 생성자 내에서 다른 생성자를 this( ... ) 형태로 불렀다면 그것은 그것대로 실행하셔야 합니다.
그건 생성자가 여러개가 불리는 것이 아니라, 생성자가 생성자끼리 부르는 것이니까 아직 객체가 태어나지 않은 것입니다.
코드 실행 순서
Main 클래스의 main() 메서드가 실행되면서 Child child = new Child();를 통해 Child 객체를 생성합니다.
Child 클래스의 생성자가 호출됩니다. 이 생성자 내부에서는 먼저 super("안녕하세요, Parent입니다.");를 통해 부모 클래스인 Parent의 생성자를 명시적으로 호출합니다.
Parent 클래스의 생성자가 호출됩니다. 여기서 System.out.println("Parent 클래스의 생성자: " + message);가 실행되며, "Parent 클래스의 생성자: 안녕하세요, Parent입니다."라는 메시지가 출력됩니다.
Parent 클래스의 생성자가 끝나면 다시 Child 클래스의 생성자의 남은 부분이 실행됩니다. 즉, System.out.println("Child 클래스의 생성자");가 실행되며 "Child 클래스의 생성자"라는 메시지가 출력됩니다.
Child 클래스의 생성자가 종료되면 main() 메서드의 실행도 끝납니다.
자식이 태어난다는 기준이 뭔가요?
자식 클래스 내의 생성자가 모두 호출된 이후입니다. new 구문이 끝나면 그 코드 다음 줄부터 생성되어 있다고 생각하시면 됩니다.
물론, 자식 생성자는 부모 생성자 이후에 실행되니까 헷갈릴 수 있습니다만 코드를 해석할 때는 자식 생성자 -> 부모 생성자 super 호출 -> 그 다음에 다시 자식생성자 안으로 와서 나머지 코드 실행입니다.
실행 순서 자체는 자식 생성자 들렀다가 부모 생성자로 가는 것이 맞습니다. 우리가 Java 코드를 해석하는 입장이라고 생각해봅시다. 기본 생성자를 자동으로 호출할 지 아닐지는 결국 자식 생성자에 가서 super() 유무를 살펴봐야 알 수 있습니다.
하지만, 정보처리기사 시험에서 문제로 물어볼 때는, print 출력구문 기준으로 문제가 출제되기 때문에 부모 생성자부터 쓰신다고 생각하시면 됩니다.
네. 무조건 부모의 기본 생성자를 먼저 실행하고 자식이 생성되기 시작합니다.
이해에 도움이 되셨을까요?
0
안녕하세요, 인프런 AI 인턴입니다. 정철님 질문 주셔서 감사합니다.
자바에서 객체가 생성될 때, 기본적으로 자식 클래스의 생성자가 호출되기 전에 부모 클래스의 생성자가 먼저 호출됩니다. 즉, 자식 객체가 만들어질 때 항상 부모 객체가 먼저 생성되어야 하는 원칙 때문에, 자식 클래스의 생성자에서 부모 클래스의 기본 생성자가 자동으로 호출되는 것입니다.
그리고 “태어난다”는 표현은 객체가 실제로 생성된다는 의미로, 새로운 인스턴스를 만들기 위해 new
키워드를 사용하여 생성자를 호출할 때를 말합니다. 따라서, 자식 클래스의 생성자가 호출되기 시작할 때가 객체가 “태어나는” 순간이라고 볼 수 있습니다.
관련된 질문과 답변들을 통해 더 깊은 이해를 도울 수 있는 링크를 제공드리겠습니다.
각 링크에서는 자바의 생성자 호출 순서와 관련된 다양한 질문과 답변이 제공되고 있어 더욱 유익한 정보를 얻으실 수 있습니다. 추가적인 이미지나 코드 예제가 포함되어 있어 시각적으로 이해하는 데에도 도움이 될 것입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
먼저 주말코딩님의 강의 페르소나인 비전공 직장인으로써 노력중인데 쉽지 않네요ㅎㅎ
그리고 이렇게 자세히 설명주실 줄은 몰랐는데 상세히 설명주셔서 감사합니다.
이해는 어느정도 됐어요. 100% 이해라기보다는 조금 숙지하고 넘어간다는 느낌으로 짚어주신 부분 숙지하면서 넘어가고, 문제 반복하면서 다시 봐야겠네요 다시 한번 설명 감사합니다!