연습 문제 (5) 답지
각 문제의 풀이. 전)/후)는 코드 수정 형식.
1
1-a)
- a) 문제 없음
- c) 출력
8happiness에는 접근 제어자가 없어 패키지(default) 접근 — 같은 패키지(academy.pocu.comp2500)의Program에서 직접 접근 가능- 5 + 3 = 8
- 참고: 만약
Program이 다른 패키지에 있었다면dog.happiness는 컴파일 오류
1-b)
- a) 컴파일 오류
10000000000은int리터럴로 해석되는데int의 최댓값(2147483647)을 넘어감 (“integer number too large”).long에 대입하더라도 리터럴 자체가int라 오류
- b) 리터럴 뒤에
L을 붙여long리터럴로 만듦전) long big = 10000000000; 후) long big = 10000000000L; - c) (고친 경우 출력)
10000000000
1-c)
- a) 문제 없음
- c) 출력
8 16 2010은 8진수 → 80x10은 16진수 → 160b10은 2진수 → 2- 변수 자체에는 진법 개념이 없음 — 값은 메모리에 2진수(비트)로 저장되고, 리터럴의 진법(8/16/2진수)은 소스 코드 표기 방식일 뿐 셋 다 같은 정수값으로 컴파일됨
println은 내부적으로Integer.toString(int)를 호출하는데, 이게 그 값을 기본 10진수 문자열로 변환해 출력함 (즉 10진수로 “포맷”되는 건 저장된 값이 아니라 출력 문자열). 16진수로 보려면Integer.toHexString, 2진수는Integer.toBinaryString
2
- 출력
ID-7Item은 정적 내포 클래스라 바깥 인스턴스 없이new Catalog.Item(7)로 생성- 정적 내포 클래스는 바깥 클래스의 static 멤버(
prefix)에 접근 가능 →"ID-" + 7="ID-7"
3
접근 제어자 4가지의 접근 범위
- public: 모든 곳에서 접근 가능 (다른 패키지 포함)
- protected: 같은 패키지 + 다른 패키지의 자식 클래스에서 접근 가능
- package (아무것도 안 붙임, default): 같은 패키지 안의 클래스에서만 접근 가능
- 같은 패키지에서는 public처럼, 다른 패키지에서는 private처럼 동작
- private: 같은 클래스 내부에서만 접근 가능
4
정적 vs 비정적 내포 클래스
- a) 개체 생성 방법
- 정적(static) 내포 클래스: 바깥 인스턴스가 필요 없음 →
new Outer.Inner() - 비정적(non-static) 내포 클래스: 바깥 인스턴스가 먼저 있어야 함 →
outer.new Inner()(예:Outer outer = new Outer(); outer.new Inner();)
- 정적(static) 내포 클래스: 바깥 인스턴스가 필요 없음 →
- b) 바깥 인스턴스 멤버 접근
- 정적 내포 클래스: 바깥 클래스의 인스턴스 멤버에는 접근 불가 (static 멤버만 접근 가능). 필요하면 바깥 개체를 인자로 받아 그 참조로 접근해야 함
- 단, 바깥 개체를 인자로 받아 그 참조로 접근하면 바깥 클래스의 private 멤버 변수에도 접근 가능 (내포 클래스는 바깥 클래스의 멤버라 private도 보임)
- 비정적 내포 클래스: 바깥 인스턴스에 묶여 있으므로 바깥의 인스턴스 멤버(심지어 private)에도 접근 가능
- 정적 내포 클래스: 바깥 클래스의 인스턴스 멤버에는 접근 불가 (static 멤버만 접근 가능). 필요하면 바깥 개체를 인자로 받아 그 참조로 접근해야 함
- 정리: 바깥 인스턴스 멤버가 필요 없으면 정적, 필요하면 비정적을 사용
5
5-a)
- a) 문제 없음
- c) 출력
105StaticInner는 정적 내포 클래스 →new Outer.StaticInner(5)로 생성compute()=this.n+staticValue(바깥 static) = 5 + 100 = 105
5-b)
- a) 컴파일 오류
Inner는 비정적 내포 클래스라 바깥 인스턴스 없이new Outer.Inner()로 생성할 수 없음
- b) 바깥 개체를 먼저 만들고
outer.new Inner()로 생성전) Outer.Inner inner = new Outer.Inner(); 후) Outer outer = new Outer(); Outer.Inner inner = outer.new Inner();- (고친 경우 출력)
110(instanceValue10 +staticValue100 )
- (고친 경우 출력)
5-c)
- a) 컴파일 오류
- 정적 내포 클래스(
StaticInner)는 바깥 클래스의 인스턴스 멤버(instanceValue)에 접근할 수 없음 (static 멤버만 가능)
- 정적 내포 클래스(
- b) 바깥 인스턴스를 인자로 받아 그 참조로 접근하거나, 해당 값을 static으로 두거나,
instanceValue사용을 빼야 함
6
- 출력
two threex가 2라case 2로 진입 → “two” 출력case 2에break가 없어 fall-through로case 3까지 실행 → “three” 출력 후break로 종료- Java는
break를 빼먹은 fall-through를 컴파일 단계에서 막아주지 않음
7
- 출력
7- i=1 → sum=1
- i=2 → sum=3
- i=3 →
continue로 건너뜀 (sum 그대로 3) - i=4 → sum=7
- i=5 →
break로 반복 종료 (더하지 않음) - 최종 sum=7
8
예시 답안
// GameConfig.java
package academy.pocu.comp2500;
public class GameConfig {
private static GameConfig instance;
private int difficulty;
private GameConfig() {
}
public static GameConfig getInstance() {
if (instance == null) {
instance = new GameConfig();
}
return instance;
}
public int getDifficulty() {
return this.difficulty;
}
public void setDifficulty(int difficulty) {
this.difficulty = difficulty;
}
}
// Program.java
package academy.pocu.comp2500;
public class Program {
public static void main(String[] args) {
GameConfig.getInstance().setDifficulty(3);
System.out.println(GameConfig.getInstance().getDifficulty());
}
}- 포인트
private생성자로 외부에서new GameConfig()를 막음private static GameConfig instance에 단 하나의 인스턴스를 보관하고,getInstance()에서 처음 호출 시에만 생성(지연 초기화)- 두 번의
getInstance()가 같은 개체를 반환하므로 출력은3 - 클래스 이름으로 인스턴스 메서드를 바로 호출(
GameConfig.getDifficulty())할 수는 없고, 반드시getInstance()로 개체를 거쳐야 함
9
- 출력
80setHp(120): 100 초과라 거부(상태 유지) → hp=50setHp(-10): 0 미만이라 거부(상태 유지) → hp=50setHp(80): 유효 → hp=80- setter에서 유효성 검사를 해 개체가 항상 유효한 상태(0~100)를 유지함
10
생성자에서 초기화해야 하는 이유 (예시)
- 개체가 생성과 동시에 유효한 상태가 됨 (후조건)
- 생성자도 함수라 선조건/후조건이 적용됨. 생성자의 후조건은 “개체의 상태는 개체 생성과 동시에 유효하다”
- 개체를 만든 뒤 따로 값을 대입하면 그 사이에 속이 빈(유효하지 않은) 개체가 존재 → 개념상 이상함 (공장에서 나온 콜라가 캔만 있고 내용물이 없는 격)
- 사용자의 실수 방지
- 그 클래스를 쓰는 사용자(코드/프로그래머)가 “어떤 멤버를, 어떤 값으로 초기화해야 하는지” 일일이 신경 쓰지 않아도 됨
- 나중에 멤버 변수가 추가돼도 생성자만 고치면 되어, 흩어진 초기화 코드의 누락 위험이 줄어듦
- 생성자는 계약(contract)
- 필요한 값을 인자로 강제해, “그 값을 주면 유효한 개체를 만들어 준다”는 계약 역할을 함
- 함수는 블랙박스이며, 이는 캡슐화·데이터 추상화와 같은 맥락
11
- 출력
false true falseDoor는Lock을 상속(is-a)하지 않고 멤버로 가짐(has-a) → 컴포지션boolean멤버locked의 기본값은false→ 처음isLocked()는falseclose()는 보관한Lock에 위임해 잠금(lock()→ true),open()은 풂(unlock()→ false)- 즉
Door는 상태 관리를Lock에 위임(delegation)함