메서드는 객체를 따르고 필드는 참조를 따른다. 생성자는 부모부터. 오버로딩은 컴파일 때, 오버라이딩은 실행 때. 네 문장이 17문항이다
왜 이 장을 하나
Java 문제의 함정은 언제나 지금 실행되는 것이 부모 코드인가 자식 코드인가다. 오버라이딩된 메서드는 객체의 실제 타입(new 뒤)을 따르고, 필드와 static 메서드와 오버로딩은 참조 변수의 타입(선언 쪽)을 따른다. 이 갈림 하나에 17문항이 걸려 있다.
다루는 것상속 · 오버라이딩 · 오버로딩 · 생성자 순서 · super · this · 인터페이스 · 추상 클래스
문항기출 17 · 예상 2 · 훈련 10
끝나면호출마다 객체 타입인지 참조 타입인지 가른다
01왜 이 장인가
왜 이걸 하나 — Java 34문항 중 17문항이 이 장이고 11회 중 10회에 나왔다. 2026년 2회에는 2문항이었다.
11회분 220문항 중 이 장의 기출은 17문항이다. 2023년 1회부터 2026년 2회까지 2024년 2회만 빼고 매 회 나왔고, 2023년 1회 · 3회 · 2024년 3회 · 2025년 3회 · 2026년 2회에는 2문항씩이었다. 훈련 Java 10문항(1~3 · 5 · 16~19 · 27 · 30)이 붙는다.
→ 17문항 중 11문항이 참조 타입 vs 객체 타입 하나로 갈린다. 2024년 3회 17번(a.x 는 부모 필드, a.getX() 는 자식 메서드)과 2025년 2회 10번(static 메서드는 참조 타입)이 이 규칙의 양쪽 끝이다.
E01 진단의 Java 3문항 중 9번(super.print → 10a20b)과 16번(재정의된 func → 509)이 이 장이다. Java 를 4년 써 온 개발자에게도 시험의 함정은 실무와 다른 자리에 있다 — 필드는 오버라이딩되지 않는다는 것과 오버로딩은 컴파일 때 정해진다는 것이다.
문항 수는 이 노트의 문제 데이터에서 ch=E05 인 것을 센 값이다(2026-09-14). 기출 코드는 grandlife.co.kr 복원에서 옮겼고, 17문항 전부 JDK 17 로 실행하거나(키워드 빈칸 2개는 채워서) 컴파일해 정답을 확인했다. 실행 순서 문제(2024-1회 10번)는 코드 추적으로 확인했다.
02한눈에
왜 이걸 하나 — 시험 전날 규칙 8개를 다시 본다. 전부 「누구를 따르나」다.
오버라이딩 — 객체를 따른다Parent p = new Child(); 에서 p.method() 는 Child 의 것. 부모 코드 안에서 자기를 부르는 draw() 도 자식 것이 실행된다(동적 바인딩). 재귀 호출도 마찬가지.
필드 — 참조를 따른다필드는 오버라이딩되지 않는다. p.x 는 Parent 의 x. 자식에 같은 이름의 x 가 있어도 참조 타입이 Parent 면 Parent 것. 메서드 안의 x 는 그 메서드가 속한 클래스의 x.
static 메서드 — 참조를 따른다static 메서드는 오버라이딩이 아니라 숨김(hiding). ref.tag() 는 참조 타입의 것. 인스턴스 메서드만 객체를 따른다.
오버로딩 — 컴파일 때 정해진다같은 이름 다른 매개변수. 어느 것을 부를지는 인자의 선언 타입으로 컴파일 때 결정. 정확히 일치 → 자동 형변환 → 박싱 → Object 순. 부모 코드 안의 f("a") 는 부모가 아는 시그니처 f(Object) 로 묶인다.
생성자 순서자식을 만들면 부모 생성자가 먼저(암묵적 super()). this(…) 는 같은 클래스의 다른 생성자를 먼저 부른다. 생성자 안에서 오버라이딩된 메서드를 부르면 자식 것이 실행된다.
super · thissuper.method() 는 부모 것을 명시적으로. super(a) 는 부모 생성자, 생성자의 첫 줄에만. this.x 는 내 필드, this(…) 는 내 다른 생성자.
추상 클래스 · 인터페이스abstract 메서드는 몸통 없음, 자식이 구현. 인터페이스는 implements 로 구현하고 모든 추상 메서드를 구현해야 한다. 인터페이스 타입 변수로 불러도 구현체의 코드가 돈다. 상속은 extends.
접근 제한 · 형변환private 는 자식도 못 본다(상속은 되지만 접근 불가). protected 는 자식 가능. 부모 참조 → 자식 참조는 (Child) p 캐스팅, instanceof 로 확인.
03밑바닥
왜 이걸 하나 — 규칙 8개는 「언제 정해지나」 하나로 묶인다. 컴파일 때 정해지면 참조, 실행 때 정해지면 객체.
3-1. 메서드는 실행 때, 필드는 컴파일 때
Java 는 인스턴스 메서드 호출을 실행 때 객체의 실제 클래스에서 찾는다(동적 바인딩). 그래서 NumberBox box = new SquareBox(); box.calculate(3) 은 SquareBox 의 것이 돌아 9 다(2024년 1회 16번). 부모 코드 안에서 부른 것도 같다 — 2023년 3회 1번의 Base.paint 가 부르는 draw() 는 Sub 의 draw 라 D 가 찍힌다.
필드는 다르다. 필드 접근은 컴파일 때 참조 변수의 타입으로 정해지므로 Base a = new Derived(); a.x 는 Base 의 3 이다. 2024년 3회 17번은 이 둘을 한 식에 넣었다 — a.getX() 는 Derived 것(7 × 3 = 21), a.x 는 Base 것(3), b.getX() 21, b.x 7, 합 52. 메서드는 객체 · 필드는 참조라고 두 번 갈라 적으면 된다.
2023년 3회 1번을 끝까지 따라가면 규칙이 다 보인다. value.paint() 는 Sub 의 paint → super.draw() 는 명시적이라 Base 의 draw 로 B, 그 안의 draw() 는 다시 동적 바인딩이라 Sub 의 D, 돌아와 C, this.draw() 로 D, 마지막 value.draw() 로 D → BDCDD. super 가 붙은 호출만 부모로 고정된다.
3-2. 오버로딩은 컴파일 때 시그니처로 정해진다
오버로딩은 같은 이름의 메서드를 매개변수 타입으로 고르는 것이고, 고르는 시점이 컴파일 때다. 2026년 1회 1번에서 A.g() 안의 f("a") 는 A 가 아는 메서드 f(Object) 로 묶이고, 실행 때 B 가 그 f(Object) 를 오버라이딩했으니 "2" 다. B 의 f(String) 은 A 가 모르는 시그니처라 후보에 없다.
2024년 3회 18번은 제네릭이 끼었다. Collection<T> 의 value 는 컴파일 때 Object 로 지워지므로 print(value) 는 print(Object) 가 선택돼 B0 다. 실제 값이 Integer 라도 선택은 선언 타입으로 한다. 2025년 1회 20번은 calc("5") 가 String 판을 고르고 그 안에서 int 판을 부르는 꼴이라 두 정의를 오가며 4 가 된다.
static 메서드도 참조를 따른다. 2025년 2회 10번의 ref.tag() 는 Parent 참조라 "P", 인스턴스 메서드 ref.value(2) 는 Child 것이라 5 → 5P. static 은 오버라이딩이 아니라 숨김이라는 말이 이 뜻이다.
3-3. 생성자는 부모부터, 그 안의 오버라이딩은 자식 것
자식 객체를 만들면 부모 생성자가 먼저 돈다. 명시하지 않아도 super() 가 첫 줄에 있는 셈이고, 2024년 1회 10번의 순서(main → new Child → Child 생성자 → Parent 생성자 → p.getT() → Parent 의 getT)가 그것이다 — Child 의 getT(int) 는 매개변수가 달라 오버로딩이라 Parent 의 getT() 가 실행된다.
2025년 1회 13번은 생성자 안에서 오버라이딩된 메서드를 부른다. Base() 가 update() 를 부르면 객체는 이미 Derived 라 Derived.update 가 돌고, 그 시점의 static total 에 곱이 쌓인다. total 을 줄마다 표로 적어야 54 가 나온다. this(500) 은 같은 클래스의 다른 생성자를 먼저 부르는 것이라 2023년 1회 20번의 x 가 500 이 된다.
2026년 2회 9번의 super.print() 는 부모 print 를 먼저 돌려 10a 를 찍고 이어서 20b 를 찍는다. 2026년 2회 16번은 오버라이딩된 func 이 a × c 라 500, 부모 func 은 1 + 5 + 3 = 9, 합 509. 두 문항이 이 장의 규칙 둘(super 명시 · 오버라이딩)을 한 회차에 담았다.
3-4. 인터페이스는 계약이고 키워드가 답이다
인터페이스는 메서드 이름만 정한 계약이라 구현 클래스가 implements 로 받아 전부 구현해야 한다(2025년 3회 13번). 인터페이스 타입 변수로 불러도 구현체의 코드가 도는 것은 오버라이딩과 같은 원리다 — 2024년 2회 12번의 Odd · Even 구현체가 각각 25 · 20 을 돌려준다. 부모 생성자를 부르는 예약어는 super 다(2025년 3회 14번).
통과 기준은 넷이다. 첫째, 호출 하나하나에 「메서드 → 객체 타입, 필드 · static · 오버로딩 → 참조 타입」을 적용한다. 둘째, super 가 붙은 호출만 부모로 고정된다는 것을 안다. 셋째, 생성자 순서(부모 먼저 · this() 먼저)와 생성자 안의 오버라이딩 호출을 표로 따라간다. 넷째, 제네릭 · String · int 오버로딩의 선택 규칙을 말한다. 기출 17문항이 이 넷 안에 있다.
자식에 같은 이름의 필드가 있으면 부모 참조로도 자식 필드가 보인다.필드는 오버라이딩되지 않는다. Base a = new Derived(); a.x 는 Base 의 x 다. 2024년 3회 17번의 52 와 2025년 1회 13번의 54 가 이 규칙 위에 있다. 메서드만 객체를 따른다.
부모 코드가 f("a") 를 부르면 자식의 f(String) 이 선택된다.오버로딩 선택은 컴파일 때 부모가 아는 시그니처로 한다. 부모에 f(Object) 만 있으면 그것으로 묶이고, 실행 때 자식이 f(Object) 를 오버라이딩했으면 그것이 돈다. 2026년 1회 1번의 답이 3 이 아니라 2 인 이유다.
04기출
왜 이걸 하나 — 호출마다 객체 · 참조를 표시하며 푸는 연습이다.
코드의 호출 줄마다 옆에 「객」 또는 「참」을 적고, 생성자가 있으면 부모 → 자식 순서를 번호로 적는다. 정답을 연 뒤 어느 호출에서 갈렸는지 보면 규칙 8개 중 무엇이 빠졌는지 나온다.
2023-1회 · 17번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
abstract class Vehicle {
String name;
abstract public String getName(String value);
public String getName() {
return "Vehicle name: " + name;
}
}
class Car extends Vehicle {
public Car(String value) {
name = value;
}
public String getName(String value) {
return "Car name: " + value;
}
}
public class Main {
public static void main(String[] args) {
Vehicle vehicle = new Car("Spark");
System.out.println(vehicle.getName());
}
}
정답Vehicle name: Spark
자식 객체 생성 시 부모 생성자가 먼저 실행되지만, 오버라이딩된 메서드는 항상 자식 것이 실행됩니다(동적 바인딩). "포장은 부모여도 행동은 내용물(자식)이 한다." 복원된 코드를 실행해 위 출력을 그대로 얻었다. (JDK 17) 그랜드라이프 가답안 표기는 「Vehicle name: Spark」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2023-1회 · 20번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
class Parent {
int x = 100;
Parent() {
this(500);
}
Parent(int x) {
this.x = x;
}
int getX() {
return x;
}
}
class Child extends Parent {
int x = 4000;
Child() {
this(5000);
}
Child(int x) {
this.x = x;
}
}
public class Main {
public static void main(String[] args) {
Child item = new Child();
System.out.println(item.getX());
}
}
정답500
this(값)은 "같은 클래스의 다른 생성자에게 일을 넘기는 것". 생성자 체인을 따라가며 마지막에 x에 무엇이 저장되는지 추적하면 됩니다. 복원된 코드를 실행해 위 출력을 그대로 얻었다. (JDK 17) 그랜드라이프 가답안 표기는 「500」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2023-3회 · 1번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
class Base {
public void paint() {
System.out.print("A");
draw();
}
public void draw() {
System.out.print("B");
draw();
}
}
class Sub extends Base {
public void paint() {
super.draw();
System.out.print("C");
this.draw();
}
public void draw() {
System.out.print("D");
}
}
public class Main {
public static void main(String[] args) {
Base value = new Sub();
value.paint();
value.draw();
}
}
정답BDCDD
부모 타입 변수로 호출해도 오버라이딩된 메서드는 자식 것이 실행됩니다. 호출 스택을 종이에 그리며 "지금 누구의 메서드인가"를 한 줄씩 추적하는 연습이 필수. 복원된 코드를 실행해 위 출력을 그대로 얻었다. (JDK 17) 그랜드라이프 가답안 표기는 「BDCDD」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2023-3회 · 14번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
class Parent {
int compute(int number) {
if (number <= 1) {
return number;
}
return compute(number - 1) + compute(number - 2);
}
}
class Child extends Parent {
int compute(int number) {
if (number <= 1) {
return number;
}
return compute(number - 1) + compute(number - 3);
}
}
public class Main {
public static void main(String[] args) {
Parent value = new Child();
System.out.print(value.compute(7));
}
}
정답2
재귀 호출 중에도 오버라이딩된 메서드는 계속 자식 것이 실행된다는 점이 핵심. 부모 코드 안에서 자기 자신을 호출해도 동적 바인딩은 유지됩니다. 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「2」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2024-1회 · 10번Java
다음 Java 코드에서 번호가 붙은 부분의 실행 순서를 중복 번호 없이 쓰시오.
class Parent {
Parent(int a, int b) { } // ①
void getT() { } // ②
}
class Child extends Parent {
Child(int x) { // ③
super(x + 1, x);
}
void getT(int value) { } // ④
}
public class Main {
public static void main(String[] args) { // ⑤
Parent p = new Child(3); // ⑥
p.getT(); // ⑦
}
}
정답⑤ → ⑥ → ③ → ① → ⑦ → ②
철칙 3개: ① 자식 생성 시 부모 생성자 먼저 ② 오버라이딩 메서드는 항상 자식 것 실행 ③ static 블록은 클래스 로딩 시 최초 1회. 이 셋으로 모든 순서 문제가 풀립니다. 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「⑤ → ⑥ → ③ → ① → ⑦ → ②」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2024-1회 · 16번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
class NumberBox {
int calculate(int n) {
return n + 1;
}
}
class SquareBox extends NumberBox {
@Override int calculate(int n) {
return n * n;
}
}
public class Main {
public static void main(String[] args) {
NumberBox box = new SquareBox();
System.out.print(box.calculate(3));
}
}
정답9
오버라이딩 문제의 승부처는 "지금 실행되는 게 부모 코드인가 자식 코드인가". 객체의 실제 타입(new 뒤의 클래스)이 항상 기준입니다. 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「9」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2024-2회 · 12번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
public class Main {
public static void main(String[] args) {
int odd = 0;
int even = 0;
for (int i = 1; i <= 9; i++) {
if (i % 2 == 0)
even += i;
else
odd += i;
}
System.out.printf("%d, %d", odd, even);
}
}
정답25, 20
1~9 홀수 합=25, 2~8 짝수 합=20. 인터페이스는 "계약서" — implements한 클래스가 반드시 메서드를 구현해야 하며, 인터페이스 타입 변수로 호출해도 구현체의 코드가 실행됩니다. 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「25, 20」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2024-3회 · 17번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
public class Main {
public static void main(String[] args) {
Base a = new Derived();
Derived b = new Derived();
System.out.print(a.getX() + a.x + b.getX() + b.x);
}
}
class Base {
int x = 3;
int getX() {
return x * 2;
}
}
class Derived extends Base {
int x = 7;
int getX() {
return x * 3;
}
}
정답52
"변수(필드)는 참조 타입, 메서드는 실제 객체 타입을 따른다" — 필드는 오버라이딩되지 않는다는 것이 Java 최고급 함정입니다. 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「52」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2024-3회 · 18번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
class Printer {
void print(Integer value) {
System.out.print("A" + value);
}
void print(Object value) {
System.out.print("B" + value);
}
void print(Number value) {
System.out.print("C" + value);
}
}
public class Main {
static class Collection<T> {
T value;
Collection(T value) {
this.value = value;
}
void print() {
new Printer().print(value);
}
}
public static void main(String[] args) {
new Collection<>(0).print();
}
}
정답B0
오버로딩 선택은 컴파일 시점의 매개변수 타입으로 결정(정적), 오버라이딩은 실행 시점의 객체 타입(동적). 이 대비가 2026년 1회 1번 문제로 다시 출제된 핵심 원리! 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「B0」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2025-1회 · 13번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
public class Main {
public static void main(String[] args) {
new Derived();
System.out.println(Base.total);
}
}
class Base {
static int total = 0;
int value = 1;
Base() {
total += ++value;
update();
}
void update() {
total += total;
}
}
class Derived extends Base {
int value = 10;
Derived() {
value += 2;
total += value++;
update();
}
@Override void update() {
total += total * 2;
}
}
정답54
오버라이딩(실행 시점, 객체 타입)과 필드 접근(컴파일 시점, 참조 타입)을 분리해서 추적 — Java 계산 문제의 영원한 핵심. 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「54」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2025-1회 · 20번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
public class Main {
static int calc(int value) {
if (value <= 1)
return value;
return calc(value - 1) + calc(value - 2);
}
static int calc(String text) {
int value = Integer.parseInt(text);
if (value <= 1)
return value;
return calc(value - 1) + calc(value - 3);
}
public static void main(String[] args) {
System.out.println(calc("5"));
}
}
정답4
오버로딩 선택 규칙: 정확히 일치하는 타입 > 자동 형변환 가능한 타입 > Object. int 인자는 int 버전이 있으면 그것부터. 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「4」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2025-2회 · 10번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
public class Main {
static class Parent {
int value(int n) {
return n + 2;
}
static String tag() {
return "P";
}
}
static class Child extends Parent {
int value(int n) {
return n + 3;
}
static String tag() {
return "C";
}
}
public static void main(String[] args) {
Parent ref = new Child();
System.out.print(ref.value(2) + ref.tag());
}
}
정답5P
최고급 함정: static 메서드는 오버라이딩되지 않습니다(숨김, hiding). 인스턴스 메서드는 객체 타입, static 메서드는 참조 타입을 따릅니다. 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「5P」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2025-3회 · 13번Java
다음 Java 프로그램의 빈칸에 들어갈 키워드를 쓰시오.
interface Machine {
void run();
}
class Washer ① Machine {
public void run() {
System.out.print("RUN");
}
}
정답implements
클래스 상속=extends, 인터페이스 구현=implements. "계약서(인터페이스)에 서명(implements)한다"로 연상. 확인 방법: implements 키워드. implements 를 채우면 javac 컴파일이 통과한다 (JDK 17) 그랜드라이프 가답안 표기는 「implements」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2025-3회 · 14번Java
다음 Java 코드의 ①에 들어갈 예약어를 쓰시오.
class Rectangle {
int width;
int height;
Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
}
class Square extends Rectangle {
Square(int side) {
①(side, side);
}
int area() {
return width * height;
}
}
정답super
super() = 부모 생성자, super.메서드() = 부모 버전 메서드. this(자기 자신)와 짝으로 구분 — this()는 2023년 1회 기출. 확인 방법: super 키워드. super 를 채우면 javac 컴파일이 통과한다 (JDK 17) 그랜드라이프 가답안 표기는 「super」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2026-1회 · 1번Java
다음 Java 프로그램을 실행했을 때 출력되는 값을 쓰시오.
class A {
String f(Object x) {
return "1";
}
String g() {
return f("a");
}
}
class B extends A {
String f(Object x) {
return "2";
}
String f(String x) {
return "3";
}
}
public class Main {
public static void main(String[] args) {
A a = new B();
System.out.println(a.g());
}
}
정답2
✔ 재검증 완료: 흥달쌤 복원 시트·정처기감자 해설 일치, 시험 직후의 2 vs 3 논쟁은 2로 정리됨 (답 3을 유지하는 소스 없음). 2단계 판정: ① 오버로딩 선택은 컴파일 시점 — A 안의 코드이므로 A가 아는 시그니처 f(Object)로 결정 ② 실행은 동적 바인딩 — B가 오버라이딩한 f(Object)가 실행. B의 f(String)은 후보조차 안 됨! 2024년 3회 Q18과 같은 원리의 심화판. 복원된 코드를 JDK 17 로 실행해 위 출력을 그대로 얻었다. 그랜드라이프 가답안 표기는 「2」. 복원 출처는 grandlife.co.kr 회차별 복원 페이지(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·값이 실제와 다를 수 있고, 문항 번호도 복원본마다 다르다.
2026-2회 · 9번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
class A {
int a;
public A(int a) {
this.a = a;
}
void print() {
System.out.print(a + "a");
}
}
class B extends A {
int b;
public B(int a, int b) {
super(a);
this.b = b;
}
@Override void print() {
super.print();
System.out.print(b + "b");
}
}
public class Main {
public static void main(String[] args) {
B obj = new B(10, 20);
obj.print();
}
}
정답10a20b
B 의 print 가 먼저 super.print() 로 부모 것을 부르므로 10a 가 찍히고, 이어서 20b. print 는 줄바꿈이 없어 한 줄로 붙는다. JDK 17 로 실행해 확인했다. 공백이나 줄바꿈을 넣으면 틀린다. 복원 출처는 grandlife.co.kr 2026-2회 복원 풀이(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·수치가 실제와 다를 수 있다.
2026-2회 · 16번Java
다음 Java 프로그램의 실행 결과를 쓰시오.
class A {
int a;
private int b;
protected int c;
A(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
int func() {
return a + b + c;
}
}
class B extends A {
B(int a, int b, int c) {
super(a, b, c);
}
@Override public int func() {
return a * c;
}
}
public class Main {
public static void main(String[] args) {
A a = new A(1, 5, 3);
B b = new B(10, 30, 50);
System.out.print(a.func() + b.func());
}
}
정답509
a.func() 는 1+5+3 = 9. b.func() 는 B 가 재정의한 것이 불려 10×50 = 500. 둘 다 int 라 + 는 덧셈이고 9+500 = 509. JDK 17 로 실행해 확인했다. 문자열이 끼면 이어 붙이기가 되지만 여기는 숫자뿐이다. private b 는 B 에서 못 보지만 이 문제에서는 쓰지 않는다. 복원 출처는 grandlife.co.kr 2026-2회 복원 풀이(2026-09-14 대조). 공식 원문이 아니라 문장·변수명·수치가 실제와 다를 수 있다.
예상 1회 · 1번Java빈출 원리: 오버라이딩 vs 필드
다음 코드의 출력을 쓰시오.
class Animal {
String name = "Animal";
void cry() { System.out.print("A"); }
void sound() { cry(); System.out.print(name); }
}
class Dog extends Animal {
String name = "Dog";
void cry() { System.out.print("D"); }
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog();
a.sound();
System.out.print(a.name);
}
}
정답DAnimalAnimal
메서드는 오버라이딩되지만 필드는 오버라이딩되지 않습니다. cry()는 동적 바인딩으로 Dog의 "D". 하지만 sound() 안의 name은 Animal 클래스 코드이므로 Animal의 "Animal", a.name도 참조 타입(Animal) 기준 "Animal". 2024 3회 Q17·2025 1회 Q13의 핵심 원리.
예상 2회 · 8번Java빈출 원리: super + 동적 바인딩
다음 코드의 출력을 쓰시오.
class A {
int f() { return 3; }
int g() { return f() + 1; }
}
class B extends A {
int f() { return 5; }
int g() { return super.g() + f(); }
}
public class Main {
public static void main(String[] args) {
System.out.print(new B().g());
}
}
정답11
B.g() → super.g()는 A의 g() 코드를 실행하지만, 그 안의 f()는 동적 바인딩으로 B.f()=5 → 5+1=6. 여기에 +f()=5 → 11. "super는 부모의 코드를 빌릴 뿐, 오버라이딩은 여전히 살아있다" — 최고급 함정.
05틀리는 자리
왜 이걸 하나 — Java 는 원리를 알아도 한 호출에서 갈려 통째로 깎인다.
자리
새는 꼴
적는 법
기출
필드
a.x 를 자식 값으로 읽는다
필드는 참조 타입. 메서드만 객체 타입
2024-3회 17번 · 2025-1회 13번
static
ref.tag() 를 자식 것으로
static 메서드는 참조 타입(숨김)
2025-2회 10번
오버로딩 후보
부모가 모르는 f(String) 을 고른다
부모 코드 안의 호출은 부모의 시그니처로 묶인다
2026-1회 1번
제네릭
T 를 Integer 로 보고 print(Integer)
T 는 Object 로 지워진다
2024-3회 18번
super 범위
super.draw() 안의 draw() 도 부모로
super 가 붙은 그 호출만 부모. 안에서 부르는 것은 다시 객체
2023-3회 1번
생성자 순서
자식 생성자 본문을 부모보다 먼저
super() 가 첫 줄. this() 도 먼저
2024-1회 10번 · 2023-1회 20번
오버로딩 · 오버라이딩
getT(int) 를 getT() 의 오버라이딩으로
매개변수가 다르면 오버로딩 — 부모 것이 그대로 남는다
2024-1회 10번
표기
10a20b 를 「10a 20b」로, 순서를 번호 없이
print 는 줄바꿈 없음. 순서 문제는 문제의 번호 표기 그대로
2026-2회 9번 · 2024-1회 10번
Java 출력 문제는 print 와 println 의 차이가 줄바꿈을 정한다. 코드에서 println 을 동그라미 치고, 답의 줄 수를 그 개수에 맞춘다.
06훈련
왜 이걸 하나 — 규칙 8개를 짧은 코드 10개로 돌린다. 매일 5문항씩 곁들이는 자리다.
훈련 10문항은 동적 바인딩, 필드 비오버라이딩, 생성자 순서와 super, 오버로딩 선택, instanceof 와 캐스팅, 인터페이스, 추상 클래스, static 숨김, 2026년 1회 1번 원리 재훈련, this() 체인이다. 정답은 전부 JDK 17 로 실행해 확인했다.
훈련 Java · 1번Java동적 바인딩 기본
class A { void show() { System.out.print("P"); } }
class B extends A { void show() { System.out.print("C"); } }
public class Main {
public static void main(String[] args) {
A obj = new B();
obj.show();
obj = new A();
obj.show();
}
}
정답CP
메서드는 내용물(실제 객체)이 결정: new B()면 C, new A()로 갈아끼우면 P.
훈련 Java · 2번Java필드는 오버라이딩되지 않는다
class A { int x = 10; int get() { return x; } }
class B extends A { int x = 20; int get() { return x; } }
public class Main {
public static void main(String[] args) {
A o = new B();
System.out.print(o.x + " " + o.get());
}
}
정답10 20
필드는 참조 타입(A)의 것(10), 메서드는 객체 타입(B)의 것(20). Java 최고 빈출 함정 — 2024 3회 Q17의 원리.
훈련 Java · 3번Java생성자 호출 순서 + super
class A {
A() { System.out.print("A"); }
A(int n) { System.out.print("A" + n); }
}
class B extends A {
B() { System.out.print("B"); }
B(int n) { super(n); System.out.print("B" + n); }
}
public class Main {
public static void main(String[] args) {
new B();
new B(5);
}
}
정답ABA5B5
new B() → 암묵적 super()로 "A" 먼저, 그다음 "B". new B(5) → super(5)로 "A5", 그다음 "B5". 부모가 항상 먼저!
오버로딩은 인자 타입과 정확히 맞는 것 우선. double을 출력하면 3.0처럼 소수점이 붙는 것까지 정답의 일부!
훈련 Java · 16번Javainstanceof + 캐스팅
Object o = "text";
if (o instanceof String) {
String s = (String) o;
System.out.print(s.length());
} else System.out.print("no");
정답4
instanceof = "내용물 확인 후 개봉". "text"는 String이므로 캐스팅 성공, 길이 4.
훈련 Java · 17번Java인터페이스 구현체 호출
interface Calc { int calc(int n); }
class Odd implements Calc {
public int calc(int n) {
int s = 0;
for (int i = 1; i <= n; i += 2) s += i;
return s;
}
}
// main:
Calc c = new Odd();
System.out.print(c.calc(9));
정답25
1+3+5+7+9=25. 인터페이스 타입 변수로 불러도 구현체(Odd)의 코드가 실행 — 2024 2회 Q12 유형.
훈련 Java · 18번Java추상 클래스
abstract class Shape {
abstract int area();
void print() { System.out.print("area:" + area()); }
}
class Rect extends Shape {
int w = 3, h = 4;
int area() { return w * h; }
}
// main:
Shape s = new Rect();
s.print();
정답area:12
부모의 print() 안에서 호출한 area()도 동적 바인딩 → Rect의 3×4=12. "골격은 부모, 세부는 자식" = 템플릿 메서드 패턴의 원리이기도.
훈련 Java · 19번Javastatic 메서드는 오버라이딩되지 않는다
class A { static void f() { System.out.print("SA"); } void g() { System.out.print("IA"); } }
class B extends A { static void f() { System.out.print("SB"); } void g() { System.out.print("IB"); } }
// main:
A x = new B();
x.f();
x.g();
정답SAIB
static 메서드는 참조 타입(A) 기준(SA), 인스턴스 메서드는 객체 타입(B) 기준(IB). 2025 2회 Q10 "5P"의 정체가 바로 이것.
훈련 Java · 27번Java2026년 1회 1번 원리 재훈련
class A {
void g() { f("a"); }
void f(Object o) { System.out.print("AO"); }
}
class B extends A {
void f(Object o) { System.out.print("BO"); }
void f(String s) { System.out.print("BS"); }
}
// main:
A x = new B();
x.g();
정답BO
g()는 A의 코드 → A가 아는 시그니처는 f(Object)뿐(오버로딩은 컴파일 시점 결정) → 실행은 동적 바인딩으로 B의 f(Object)="BO". B의 f(String)은 후보조차 아님. 실제 2026년 1회 1번이 이 원리였습니다.
훈련 Java · 30번Javathis() 생성자 체인
class X {
int x;
X() { this(7); System.out.print("K"); }
X(int n) { x = n; System.out.print("L"); }
}
// main:
X o = new X();
System.out.print(o.x);
정답LK7
this(7)이 먼저 X(int) 실행("L", x=7) → 돌아와서 "K" → o.x=7. 2023 1회 Q20 this() 유형의 재훈련.
직접 돌려 보는 법
JDK 17 이 깔려 있으니 코드를 Main.java 로 저장하고 파워셸에서 아래를 치면 된다. 클래스 이름이 파일 이름과 같아야 하고, public class 가 하나여야 한다.
javac -encoding UTF-8 Main.java; java Main
이 장의 기출 17개 · 훈련 10개는 위 명령(JDK 17.0.12)으로 실행해 답을 확인했다. 클래스 선언과 문장이 섞인 훈련 코드는 클래스는 밖으로, 문장은 main 안으로 옮겨 컴파일했다.
07백지 재현
왜 이걸 하나 — 아래를 안 보고 적을 수 있어야 이 장이 끝난다.
객체 타입을 따르는 것 하나(인스턴스 메서드)와 참조 타입을 따르는 것 셋(필드 · static · 오버로딩).
super 가 붙은 호출과 안 붙은 호출의 차이, 2023년 3회 1번의 BDCDD 를 다시 만들기.
자식 객체 생성 시 실행 순서, this() 와 super() 의 위치.
오버로딩 선택 규칙(정확 → 형변환 → 박싱 → Object)과 제네릭 T 의 지워짐.
implements · extends · abstract · super 의 쓰임.
메서드는 객체, 필드 · static · 오버로딩은 참조를 따른다.
super 가 붙은 호출만 부모로 고정된다.
생성자는 부모부터, 그 안의 오버라이딩은 자식 것.
오버로딩은 컴파일 때 부모가 아는 시그니처로 묶인다.
E06 Java static · 예외 · String · 참조 — static 공유, try-catch-finally 순서, == 와 equals, 배열 · 객체 참조 복사, 문자열 연결 순서, 람다 · enum. Java 의 나머지 절반이다.