해결된 질문
작성
·
58
0
안녕하세요 선생님.
33분 대 자바 문제에서
제가 이해한 바가 맞는지 궁금해 질문 드립니다.
------------------------------------
업캐스팅 되지 않은 상태로 obj가 태어났고
child() 생성자를 찾으러 올라갔고,
업캐스팅 여부와 상관 없이 새로 객체가 태어나게 되면 child()를 실행하기 전에 -> 자동으로 parent()로 올라가게 됩니다.
parent() 안에 있는 this(500)으로 인해 parent(500)을 실행하게 되고,
parent의 int x가 100에서 500으로 바뀝니다.
그리고 다시 child()로 돌아와서 this(5000) -> child(5000) -> child.x는 4000에서 5000으로 바뀌게 됩니다.
다시 메인으로 내려와서 system.out.println(obj.getX())를 실행하게 되고
child 클래스에는 getX가 없기 때문에 parent 클래스로 올라가서 getX()를 찾습니다.
그래서 return x로 인해 parent의 500을 답으로 돌려주게 됩니다.
---------------------------------
[질문]
1. 제가 위에 적어놓은 풀이과정이 맞나요?
2. 업캐스팅 여부와 상관 없이, 업캐스팅 됐든 되지 않았든 새로 객체가 태어나게 되면
child()를 실행하기 전에 -> 자동으로 parent()로 올라가게 되나요?
3. 만약 Child obj2 = new Child(300) 이렇게 태어나게 되면 Child(int x)로 올라갔다가 -> 자동으로 Parent(int x)로 올라가게 되나요? 아니면 이 경우는 기본생성자 형태가 아니기 때문에 super로 부모를 명시해야 하나요?
4. system.out.println(obj.getX())를 실행할 때, child 클래스에 getX가 있었다면 메서드 오버라이딩으로 인해 parent 클래스로 올라가지 않나요?
질문이 너무 많은 거 같은데 죄송합니다..
다시 한 번 개념을 정립하고 싶어 길게 질문드렸습니다.
답변 주시면 감사하겠습니다..
답변 2
0
질문은 얼마든지 많이 하셔도 됩니다.
다만 하나에 대해서는 하나씩 질문을 올려주시면 다른 분들이 보기에도 더 좋지 않을까 싶습니다.
해당 코드의 대략적인 구조는 이렇습니다.
Main ──> Child() // 기본 생성자 호출
└─ this(5000) // Child(int) 로 이동
├─ implicit super() // 컴파일러가 자동으로 Parent() 삽입
│ └─ this(500) // Parent(int) 호출
│ └─ Parent.x = 500
├─ Child.x = 5000 // Child(int) 본문
└─ return… // 호출 사슬 종료
System.out.println(obj.getX()) // Parent.getX() 실행 → 500
질문에 대한 답변입니다.
1. 제가 위에 적어놓은 풀이과정이 맞나요?
네 맞습니다. 각각 바뀌는 변수도 맞고, 자식한테 없어서 부모가 실행되는 것도 맞습니다.
2. 업캐스팅 여부와 상관 없이, 업캐스팅 됐든 되지 않았든 새로 객체가 태어나게 되면 child()를 실행하기 전에 -> 자동으로 parent()로 올라가게 되나요?
네. 객체 생성 시점에 업캐스팅이 일어나든 말든 다음 규칙이 항상 적용됩니다.
모든 생성자의 첫 줄에는
this(...)
(같은 클래스의 다른 생성자) 또는
super(...)
(부모 클래스 생성자)
중 하나만 위치할 수 있습니다.
둘 다 없으면 컴파일러가 super();
를 자동 삽입합니다.
따라서 부모 생성자는 반드시 한 번 호출됩니다.
업캐스팅은 참조 변수 타입에 따라 달라지는 것으로 생성자 호출 순서와는 크게 상관없습니다.
3. 만약 Child obj2 = new Child(300) 이렇게 태어나게 되면 Child(int x)로 올라갔다가 -> 자동으로 Parent(int x)로 올라가게 되나요? 아니면 이 경우는 기본생성자 형태가 아니기 때문에 super로 부모를 명시해야 하나요?
new Child(300)이라면, Child(int x)가 호출되긴 하는데 그 안에서 부모 생성자를 들렀다가 다시 돌아옵니다. 그러니까 결국 부모 생성자가 먼저 실행된다고 외우시면 됩니다.
Parent(500)하고 다시 돌아와서 child(300)을 실행하면 됩니다.
4. system.out.println(obj.getX())를 실행할 때, child 클래스에 getX가 있었다면 메서드 오버라이딩으로 인해 parent 클래스로 올라가지 않나요?
Child가 오버라이딩 했다면, Child.getX()가 실행됩니다.
0
안녕하세요, 인프런 AI 인턴입니다. 김영서님.
자바 객체 생성 및 상속에 관한 질문 잘 읽었습니다. 다양한 개념들이 포함되어 있어 조금 헷갈릴 수 있는 주제입니다. 단계별로 설명드리겠습니다.
풀이 과정의 정확성:
this(500)
이 부모 클래스에서 호출되면 부모 생성자 중 매개변수가 있는 생성자가 실행됩니다.system.out.println(obj.getX())
에서 자식 클래스에 getX()
메서드가 없을 때 부모 클래스의 메서드가 호출되는 것은 정확합니다.업캐스팅 여부와 생성자 호출:
매개변수가 있는 생성자의 경우:
Child obj2 = new Child(300);
의 경우, 자식 클래스의 매개변수를 받는 생성자가 호출됩니다. 자식 클래스의 생성자에서 명시적으로 super(x)
형태로 부모 클래스의 특정 생성자를 호출하지 않는다면 부모 클래스의 기본 생성자는 자동으로 호출되지 않으므로 컴파일 오류가 발생할 수 있습니다. 따라서 부모 클래스의 매개변수를 받는 생성자를 호출하도록 명시적으로 작성해야 합니다.Method Overriding 및 메서드 호출:
Child
클래스에 getX()
메서드가 존재하고 부모 클래스의 getX()
메서드를 오버라이딩 하고 있다면, 오버라이딩 된 Child
클래스의 getX()
메서드가 호출됩니다. 이는 자바의 다형성(polymorphism)에 따른 규칙입니다.자바 상속 및 생성자에 관련된 주제를 더 깊이 이해하시기 위해서는 아래의 링크를 참고하시면 도움이 될 것입니다:
- 자바에서 생성자 호출 순서에 대한 설명
- 자바 다형성과 오버라이딩 관련 설명
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.