๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
BackEnd๐ŸŒฑ/Java

[Java] ์ธํ„ฐํŽ˜์ด์Šค(interface) ์ด ์ •๋ฆฌ

by dkswnkk 2022. 3. 30.

์„œ๋ก 

Spring ๊ณต๋ถ€ํ•˜๋˜ ์ค‘ interface๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ดํ•ด๊ฐ€ ๋ถ€์กฑํ•œ ๊ฒƒ ๊ฐ™์•„ ์ž์„ธํ•˜๊ฒŒ ํ•œ๋ฒˆ ์ •๋ฆฌํ•ด ๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๋ชฉ์ฐจ
1. ์ธํ„ฐํŽ˜์ด์Šค๋ž€?
2. ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ž‘์„ฑ ๋ฐฉ๋ฒ•
3. ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ƒ์†
4. ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„
5. ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•œ ๋‹คํ˜•์„ฑ
6. ์ธํ„ฐํŽ˜์ด์Šค์˜ ์žฅ์ 

 

1. ์ธํ„ฐํŽ˜์ด์Šค๋ž€?

์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ผ์ข…์˜ ์ถ”์ƒ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ถ”์ƒ ํด๋ž˜์Šค์ฒ˜๋Ÿผ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–์ง€๋งŒ ์ถ”์ƒ ํด๋ž˜์Šค๋ณด๋‹ค ์ถ”์ƒํ™” ์ •๋„๊ฐ€ ๋†’์•„์„œ ์ถ”์ƒ ํด๋ž˜์Šค์™€ ๋‹ฌ๋ฆฌ ๋ชธํ†ต์„ ๊ฐ–์ถ˜ ์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ ๋˜๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ๊ตฌ์„ฑ์›์œผ๋กœ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ค์ง "์ถ”์ƒ ๋ฉ”์„œ๋“œ"์™€ "์ƒ์ˆ˜"๋งŒ์„ ๋ฉค๋ฒ„๋กœ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ๋ถ€๋ถ„์ ์œผ๋กœ๋งŒ ์™„์„ฑ๋œ '๋ฏธ์™„์„ฑ ์„ค๊ณ„๋„'๋ผ๊ณ  ํ•œ๋‹ค๋ฉด, ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ตฌํ˜„๋œ ๊ฒƒ์€ ์•„๋ฌด๊ฒƒ๋„ ์—†๊ณ  ๋ฐ‘๊ทธ๋ฆผ๋งŒ ๊ทธ๋ ค์ ธ ์žˆ๋Š” '๊ธฐ๋ณธ ์„ค๊ณ„๋„'๋ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 ์ธํ„ฐํŽ˜์ด์Šค๋„ ์ถ”์ƒ ํด๋ž˜์Šค์ฒ˜๋Ÿผ ์™„์„ฑ๋˜์ง€ ์•Š์€ ๋ถˆ์™„์ „ํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ ์ž์ฒด๋งŒ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ๋ณด๋‹ค๋Š” ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•˜๋Š”๋ฐ ๋„์›€์„ ์ค„ ๋ชฉ์ ์œผ๋กœ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค.

 

2. ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ž‘์„ฑ ๋ฐฉ๋ฒ•

์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ํ‚ค์›Œ๋“œ๋กœ class ๋Œ€์‹  interface๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ๋งŒ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  interface์—๋„ ํด๋ž˜์Šค์™€ ๊ฐ™์ด ์ ‘๊ทผ์ œ์–ด์ž๋กœ public ๋˜๋Š” default๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

interface ์ธํ„ฐํŽ˜์ด์Šค์ด๋ฆ„{
public static final ํƒ€์ž… ์ƒ์ˆ˜์ด๋ฆ„ = ๊ฐ’;
public abstract ๋ฉ”์„œ๋“œ์ด๋ฆ„(๋งค๊ฐœ๋ณ€์ˆ˜๋ชฉ๋ก);
}

 

์ผ๋ฐ˜์ ์ธ ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„๋“ค๊ณผ ๋‹ฌ๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉค๋ฒ„๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ œ์•ฝ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

- ๋ชจ๋“  ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋Š” public static final ์ด์–ด์•ผ ํ•˜๋ฉฐ, ์ด๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.
- ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋Š” public abstract ์ด์–ด์•ผ ํ•˜๋ฉฐ, ์ด๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.(๋‹จ, static๋ฉ”์„œ๋“œ์™€ default ๋ฉ”์„œ๋“œ๋Š” JDK1.8๋ถ€ํ„ฐ ์˜ˆ์™ธ)

 

interface PlayingCard {
public static final int SPADE = 4;
final int DIAMOND = 3; // public static final int DIAMOND = 3;
static int HEART = 2; // public static final int HEART = 2;
int CLOVER = 1; // public static final int CLOVER = 1;
public abstract String getCardNumber();
String getCardKing(); // public abstract String getCardKind();
}

์ƒ๋žต๋œ ์ œ์–ด์ž๋Š” ์ปดํŒŒ์ผ ์‹œ์— ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์ ์œผ๋กœ ์œ„์™€ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ด ์ค๋‹ˆ๋‹ค.

 

3. ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ƒ์†

์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋กœ๋ถ€ํ„ฐ๋งŒ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํด๋ž˜์Šค์™€๋Š” ๋‹ฌ๋ฆฌ ๋‹ค์ค‘ ์ƒ์†, ์ฆ‰ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†์„ ๋ฐ›๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.(์ฐธ๊ณ : ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํด๋ž˜์Šค์™€ ๋‹ฌ๋ฆฌ Objectํด๋ž˜์Šค์™€ ๊ฐ™์€ ์ตœ๊ณ  ์กฐ์ƒ์ด ์—†์Šต๋‹ˆ๋‹ค.)

interface Movable {
/** ์ง€์ •๋œ ์œ„์น˜(x, y)๋กœ ์ด๋™ํ•˜๋Š” ๊ธฐ๋Šฅ์˜ ๋ฉ”์„œ๋“œ */
void move(int x, int y);
}
interface Attackable {
/** ์ง€์ •๋œ ๋Œ€์ƒ(u)์„ ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋Šฅ์˜ ๋ฉ”์„œ๋“œ */
void attack(Unit u);
}
interface Fightable extends Movable, Attackable {}

ํด๋ž˜์Šค์˜ ์ƒ์†๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ž์† ์ธํ„ฐํŽ˜์ด์Šค(Fightable)๋Š” ์กฐ์ƒ ์ธํ„ฐํŽ˜์ด์Šค(Movable, Attackable)์— ์ •์˜๋œ ๋ฉค๋ฒ„๋ฅผ ๋ชจ๋‘ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค.

 ๊ทธ๋ž˜์„œ Fightable์ž์ฒด์—๋Š” ์ •์˜๋œ ๋ฉค๋ฒ„๊ฐ€ ํ•˜๋‚˜๋„ ์—†์ง€๋งŒ ์กฐ์ƒ ์ธํ„ฐํŽ˜์ด์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›์€ ๋‘ ๊ฐœ์˜ ์ถ”์ƒ ๋ฉ”์„œ๋“œ, move(int x, int y)์™€ attack(Unit u)์„ ๋ฉค๋ฒ„๋กœ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

4. ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„

์ธํ„ฐํŽ˜์ด์Šค๋„ ์ถ”์ƒ ํด๋ž˜์Šค์ฒ˜๋Ÿผ ๊ทธ ์ž์ฒด๋กœ๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ์ถ”์ƒ ํด๋ž˜์Šค๊ฐ€ ์ƒ์†์„ ํ†ตํ•ด ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ์™„์„ฑํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์ธํ„ฐํŽ˜์ด์Šค๋„ ์ž์‹ ์—๊ฒŒ ์ •์˜๋œ ์ถ”์ƒ ๋ฉ”์„œ๋“œ์˜ ๋ชธํ†ต์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

class ClassName implements InterfaceName {
// ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์˜๋œ ์ถ”์ƒ๋ฉ”์„œ๋“œ ๊ตฌํ˜„
}
interface InterfaceName{
}

์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ตฌํ˜„ํ•œ๋‹ค๋Š” ์˜๋ฏธ์˜ ํ‚ค์›Œ๋“œ 'implements'๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ„์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

abstract class Fighter implements Fightable {
public void move(int x, int y) { /* ๋‚ด์šฉ ์ƒ๋žต */ }
}

๋งŒ์ผ ๊ตฌํ˜„ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์„œ๋“œ ์ค‘ ์ผ๋ถ€๋งŒ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด, abstract๋ฅผ ๋ถ™์—ฌ์„œ ์œ„์™€ ๊ฐ™์ด ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

class Fighter extends Unit implements Fightable {
public void move(int x, int y) { /* ๋‚ด์šฉ ์ƒ๋žต */ }
public void attack(Unit u) { /* ๋‚ด์šฉ ์ƒ๋žต */ }
}

๊ทธ๋ฆฌ๊ณ  ์œ„์™€ ๊ฐ™์ด ์ƒ์†๊ณผ ๊ตฌํ˜„์„ ๋™์‹œ์— ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•œ๋ฒˆ ์•„๋ž˜์˜ ์ „์ฒด ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ ์˜ˆ์‹œ๋กœ ๋“ค์–ด ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

class FighterTest {
public static void main(String[] args) {
Fighter f = new Fighter();
if (f instanceof Unit) {
System.out.println("f๋Š” Unitํด๋ž˜์Šค์˜ ์ž์†์ž…๋‹ˆ๋‹ค.");
}
if (f instanceof Fightable) {
System.out.println("f๋Š” Fightable์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.");
}
if (f instanceof Movable) {
System.out.println("f๋Š” Movable์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.");
}
if (f instanceof Attackable) {
System.out.println("f๋Š” Attackable์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.");
}
if (f instanceof Object) {
System.out.println("f๋Š” Objectํด๋ž˜์Šค์˜ ์ž์†์ž…๋‹ˆ๋‹ค.");
}
}
}
class Fighter extends Unit implements Fightable {
public void move(int x, int y) { /* ๋‚ด์šฉ ์ƒ๋žต */ }
public void attack(Unit u) { /* ๋‚ด์šฉ ์ƒ๋žต */ }
}
class Unit {
int currentHP; // ์œ ๋‹›์˜ ์ฒด๋ ฅ
int x; // ์œ ๋‹›์˜ ์œ„์น˜(x์ขŒํ‘œ)
int y; // ์œ ๋‹›์˜ ์œ„์น˜(y์ขŒํ‘œ)
}
interface Fightable extends Movable, Attackable {
}
interface Movable {
void move(int x, int y);
}
interface Attackable {
void attack(Unit u);
}

์œ„ ์ฝ”๋“œ์˜ ์ถœ๋ ฅ ๊ฒฐ๊ณผ
์œ„ ์ฝ”๋“œ์˜ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ„์˜ ๊ด€๊ณ„

์‹ค์ œ๋กœ Fighterํด๋ž˜์Šค๋Š” Unitํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›๊ณ  Fightable์ธํ„ฐํŽ˜์ด์Šค๋งŒ์„ ๊ตฌํ˜„ํ–ˆ์ง€๋งŒ, Unitํด๋ž˜์Šค๋Š” Objectํด๋ž˜์Šค์˜ ์ž์†์ด๊ณ , Fightable์ธํ„ฐํŽ˜์ด์Šค๋Š” Attackable๊ณผ Movable์ธํ„ฐํŽ˜์ด์Šค์˜ ์ž์†์ด๋ฏ€๋กœ Fighterํด๋ž˜์Šค๋Š” ์ด ๋ชจ๋“  ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ž์†์ด ๋˜๋Š” ์…ˆ์ด ๋ฉ๋‹ˆ๋‹ค.

 

5. ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•œ ๋‹คํ˜•์„ฑ

์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์˜ ์กฐ์ƒ์ด๋ผ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์˜ ์ฐธ์กฐ ๋ณ€์ˆ˜๋กœ ์ด๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์œผ๋กœ์˜ ํ˜• ๋ณ€ํ™˜๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 

Fightable f = new Fighter();

์˜ˆ๋ฅผ ๋“ค์–ด ์œ„์™€ ๊ฐ™์ด ์ธํ„ฐํŽ˜์ด์Šค Fightable์„ ํด๋ž˜์Šค Fighter๊ฐ€ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด Fighter์ธ์Šคํ„ด์Šค๋ฅผ Fightableํƒ€์ž…์˜ ์ฐธ์กฐ ๋ณ€์ˆ˜๋กœ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

void attack(Fightable f){
// ๋‚ด์šฉ ์ƒ๋žต
}

๋”ฐ๋ผ์„œ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์œ„์™€ ๊ฐ™์ด ๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์œผ๋กœ๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๊ฐ–๋Š” ์˜๋ฏธ๋Š” ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ œ๊ณตํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ attack๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ Fightable์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

class Fighter extends Unit implements Fightable {
public void move(int x, int y) { /* ๋‚ด์šฉ ์ƒ๋žต */}
public void attack(Fightable f) { /* ๋‚ด์šฉ ์ƒ๋žต */}
}

ํ•œ๋ฒˆ ์œ„์˜ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Fightable์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ Fighterํด๋ž˜์Šค๊ฐ€ ์žˆ์„ ๋•Œ, attack๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ Fighter์ธ์Šคํ„ด์Šค๋ฅผ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, attack(new Fighter())์™€ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

 

Fightable method() {
//...
Figther fighter = new Fighter();
return fighter;
}

๊ทธ๋ฆฌ๊ณ  ์œ„์™€ ๊ฐ™์ด ๋ฉ”์„œ๋“œ์˜ ๋ฆฌํ„ด ํƒ€์ž…์œผ๋กœ ์ธํ„ฐํŽ˜์ด์Šค์˜ ํƒ€์ž…์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ ์—ญ์‹œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋ฆฌํ„ด ํƒ€์ž…์ด ์ธํ„ฐํŽ˜์ด์Šค๋ผ๋Š” ๊ฒƒ์€ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” method()์˜ ๋ฆฌํ„ด ํƒ€์ž…์ด Fightable์ธํ„ฐํŽ˜์ด์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ์˜ return๋ฌธ์—์„œ Fightable์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ Fighterํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์˜ ๋‹คํ˜•์„ฑ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

interface Parseable {
// ๊ตฌ๋ฌธ ๋ถ„์„์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
public abstract void parse(String fileName);
}
class ParserManager {
// ๋ฆฌํ„ดํƒ€์ž…์ด Parseable์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค.
public static Parseable getParser(String type) {
if (type.equals("XML")) {
return new XMLParser();
} else {
Parseable p = new HTMLParser();
return p;
// return new HTMLParser();
}
}
}
class XMLParser implements Parseable {
public void parse(String fileName) {
/* ๊ตฌ๋ฌธ ๋ถ„์„์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ ๋Š”๋‹ค. */
System.out.println(fileName + "- XML parsing completed.");
}
}
class HTMLParser implements Parseable {
public void parse(String fileName) {
/* ๊ตฌ๋ฌธ ๋ถ„์„์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ ๋Š”๋‹ค. */
System.out.println(fileName + "-HTML parsing completed.");
}
}
class ParserTest {
public static void main(String args[]) {
Parseable parser = ParserManager.getParser("XML");
parser.parse("document.xml");
parser = ParserManager.getParser("HTML");
parser.parse("document2.html");
}
}

์ธจ๋ ฅ ๊ฒฐ๊ณผ

๋งŒ์ผ ๋‚˜์ค‘์— ์ƒˆ๋กœ์šด ์ข…๋ฅ˜์˜ NewXMLParserํด๋ž˜์Šค๊ฐ€ ๋‚˜์™€๋„ ParserTestํด๋ž˜์Šค๋Š” ๋ณ€๊ฒฝํ•  ํ•„์š” ์—†์ด, ParserManagerํด๋ž˜์Šค์˜ getParser๋ฉ”์„œ๋“œ์—์„œ 'return newXMLParser(); ๋Œ€์‹  'return new NewXMLParser();'๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์žฅ์ ์€ ํŠนํžˆ ๋ถ„์‚ฐ ํ™˜๊ฒฝ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๊ทธ ์œ„๋ ฅ์„ ๋ฐœํœ˜ํ•˜๋Š”๋ฐ, ์‚ฌ์šฉ์ž ์ปดํ“จํ„ฐ์— ์„ค์น˜๋œ ํ”„๋กœ๊ทธ๋žจ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ์„œ๋ฒ„ ์ธก์˜ ๋ณ€๊ฒฝ๋งŒ์œผ๋กœ๋„ ์‚ฌ์šฉ์ž๊ฐ€ ์ƒˆ๋กœ ๊ฐœ์ •๋œ ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

6. ์ธํ„ฐํŽ˜์ด์Šค์˜ ์žฅ์ 

๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ• ๊นŒ์š”? ๊ทธ ์žฅ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๊ฐœ๋ฐœ ์‹œ๊ฐ„์„ ๋‹จ์ถ•์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
  • ํ‘œ์ค€ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์„œ๋กœ ๊ด€๊ณ„์—†๋Š” ํด๋ž˜์Šค๋“ค์—๊ฒŒ ๊ด€๊ณ„๋ฅผ ๋งบ์–ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.
  • ๋…๋ฆฝ์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค ์žฅ์  ์˜ˆ์ œ ์ฝ”๋“œ

class RepairableTest {
public static void main(String[] args) {
Tank tank = new Tank();
Dropship dropship = new Dropship();
Marine marine = new Marine();
SCV scv = new SCV();
scv.repair(tank); // SCV๊ฐ€ Tank๋ฅผ ์ˆ˜๋ฆฌํ•˜๋„๋ก ํ•œ๋‹ค.
scv.repair(dropship);
// scv.repair(marine); // ์ฃผ์„์„ ํ’€๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋ฐœ์ƒ
}
}
interface Repairable {
}
class GroundUnit extends Unit {
GroundUnit(int hp) {
super(hp);
}
}
class AirUnit extends Unit {
AirUnit(int hp) {
super(hp);
}
}
class Unit {
int hitPoint;
final int MAX_HP;
Unit(int hp) {
MAX_HP = hp;
}
//...
}
class Tank extends GroundUnit implements Repairable {
Tank() {
super(150); // Tank์˜ HP๋Š” 150์ด๋‹ค.
hitPoint = MAX_HP;
}
public String toString() {
return "Tank";
}
//...
}
class Dropship extends AirUnit implements Repairable {
Dropship() {
super(125); // Dropship์˜ HP๋Š” 125์ด๋‹ค.
hitPoint = MAX_HP;
}
public String toString() {
return "Dropship";
}
//...
}
class Marine extends GroundUnit {
Marine() {
super(40);
hitPoint = MAX_HP;
}
//...
}
class SCV extends GroundUnit implements Repairable {
SCV() {
super(60);
hitPoint = MAX_HP;
}
void repair(Repairable r) {
if (r instanceof Unit) {
Unit u = (Unit) r;
while (u.hitPoint != u.MAX_HP) {
/* Unit์˜ HP๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค. */
u.hitPoint++;
}
System.out.println(u.toString() + "์˜ ์ˆ˜๋ฆฌ๊ฐ€ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค.");
}
}
//...
}

์ถœ๋ ฅ๊ฒฐ๊ณผ

์œ„ ์ฝ”๋“œ๋Š” ์Šคํƒ€ํฌ๋ž˜ํ”„ํŠธ ๊ฒŒ์ž„ ์œ ๋‹›์„ ๋Œ€์ƒ์œผ๋กœ ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

์ƒ์† ๊ณ„์ธต๋„

๋ชจ๋“  ์œ ๋‹›๋“ค์˜ ์ตœ๊ณ  ์กฐ์ƒ์€ Unitํด๋ž˜์Šค์ด๊ณ  ์œ ๋‹›์˜ ์ข…๋ฅ˜๋Š” ์ง€์ƒ ์œ ๋‹›(GroundUnit)๊ณผ ๊ณต์ค‘ ์œ ๋‹›(AirUnit)์œผ๋กœ ๋‚˜๋ˆ„์–ด์ง‘๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ง€์ƒ ์œ ๋‹›์—๋Š” Marine, SCV, Tank๊ฐ€ ์žˆ๊ณ , ๊ณต์ค‘ ์œ ๋‹›์œผ๋กœ๋Š” Dropship์ด ์žˆ์Šต๋‹ˆ๋‹ค. SCV์—๊ฒŒ Tank, Dropship๊ณผ ๊ฐ™์€ ๊ธฐ๊ณ„ํ™” ์œ ๋‹›์„ ์ˆ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด repair()๋ฅผ ์ •์˜ํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

void repair(Tank tank) {
// Tank๋ฅผ ์ˆ˜๋ฆฌํ•œ๋‹ค.
}
void repair(Dropship dropship) {
// Dropship์„ ์ˆ˜๋ฆฌํ•œ๋‹ค.
}

์ด๋Ÿฐ ์‹์œผ๋กœ ์ˆ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์œ ๋‹›์˜ ๊ฐœ์ˆ˜๋งŒํผ ๋‹ค๋ฅธ ๋ฒ„์ „์˜ ์˜ค๋ฒ„๋กœ๋”ฉ๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์ด ๋“ค์˜ ๊ณตํ†ต ์กฐ์ƒ์œผ๋กœ ํ•˜๋ฉด ์ข‹๊ฒ ์ง€๋งŒ Dropship์€ ๊ณตํ†ต์กฐ์ƒ์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๊ณตํ†ต์กฐ์ƒ์˜ ํƒ€์ž…์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•œ๋‹ค๊ณ  ํ•ด๋„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ตœ์†Œํ•œ 2๊ฐœ์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•„์š”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

void repair(GroundUnit groundUnit) {
// ์ง€์ƒ์œ ๋‹› ์ˆ˜๋ฆฌ
}
void repair(AirUnit airUnit) {
// ๊ณต์ค‘์œ ๋‹› ์ˆ˜๋ฆฌ
}

๊ทธ๋ฆฌ๊ณ  GroundUnit์˜ ์ž์† ์ค‘์—๋Š” Marine๊ณผ ๊ฐ™์ด ๊ธฐ๊ณ„ํ™” ์œ ๋‹›์ด ์•„๋‹Œ ํด๋ž˜์Šค๋„ ํฌํ•จ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— repair๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์œผ๋กœ GroundUnit์€ ๋ถ€์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. 

 ํ˜„์žฌ์˜ ์ƒ์†๊ด€๊ณ„์—์„œ๋Š” ์ด๋“ค์˜ ๊ณตํ†ต์ ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋•Œ๋ฌธ์— ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ธฐ์กด์˜ ์ƒ์†์ฒด๊ณ„๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ์ด๋“ค ๊ธฐ๊ณ„ํ™” ์œ ๋‹›์— ๊ณตํ†ต์ ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด Repairable์ด๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•˜๊ณ  ์ˆ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ธฐ๊ณ„ํ™” ์œ ๋‹›์—๊ฒŒ ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

interface Repairable {
}
// ์ง€์ƒ์œ ๋‹› ์ƒ์†, ์ˆ˜๋ฆฌ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„
class SCV extends GroundUnit implements Repairable {
// ...
}
// ์ง€์ƒ์œ ๋‹› ์ƒ์†, ์ˆ˜๋ฆฌ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„
class Tank extends GroundUnit implements Repairable {
// ...
}
// ๊ณต์ค‘์œ ๋‹› ์ƒ์†, ์ˆ˜๋ฆฌ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„
class Dropship extends AirUnit implements Repairable {
// ...
}

์ด์ œ ์ด 3๊ฐœ์˜ ํด๋ž˜์Šค์—๋Š” ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค๋Š” ๊ณตํ†ต์ ์ด ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค Repairable์— ์ •์˜๋œ ๊ฒƒ์€ ์•„๋ฌด๊ฒƒ๋„ ์—†๊ณ , ๋‹จ์ง€ ์ธ์Šคํ„ด์Šค์˜ ํƒ€์ž… ์ฒดํฌ์—๋งŒ ์‚ฌ์šฉ๋  ๋ฟ์ž…๋‹ˆ๋‹ค. Repairable์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์ƒ์†๊ณ„์ธต๋„๋ฅผ ๊ทธ๋ ค๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ƒ์† ๊ณ„์ธต๋„

repair๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ r์€ Repairableํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์— ์ธํ„ฐํŽ˜์ด์Šค Repairable์— ์ •์˜๋œ ๋ฉค๋ฒ„๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Repairable์—๋Š” ์ •์˜๋œ ๋ฉค๋ฒ„๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์ด ํƒ€์ž…์˜ ์ฐธ์กฐ ๋ณ€์ˆ˜๋กœ๋Š” ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์€ ์•„๋ฌด๊ฒƒ๋„ ์—†์Šต๋‹ˆ๋‹ค.

 ๊ทธ๋ž˜์„œ instanceof์—ฐ์‚ฐ์ž๋กœ ํƒ€์ž…์„ ์ฒดํฌํ•œ ๋’ค ์บ์ŠคํŒ…ํ•˜์—ฌ Unitํด๋ž˜์Šค์— ์ •์˜๋œ hitPoint์™€ MAX_HP๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋‹ค์Œ์—” ์œ ๋‹›์˜ ํ˜„์žฌ ์ฒด๋ ฅ(hitPoint)์ด ์œ ๋‹›์ด ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ตœ๊ณ  ์ฒด๋ ฅ(MAX_HP)์ด ๋  ๋•Œ๊นŒ์ง€ ์ฒด๋ ฅ์„ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 Marine์€ Repairable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ SCVํด๋ž˜์Šค์˜ repair๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ Marine์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ์‹œ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


GitHub

LinkedIn

GitHub

LinkedIn