๐โ Study Goal
- ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP) ์บก์ํ ๊ฐ๋ ์ ์ดํดํฉ๋๋ค.
- ์บก์ํ์ ํ์์ฑ์ ์์๋ด ๋๋ค.
- ์บก์ํ๊ฐ ์ฌ์ฉ๋๋ ์ฌ๋ก๋ฅผ ์ฝ๋๋ก ์์ฑํด๋ด ๋๋ค.
โ๏ธ ์บก์ํ(Encapsulation) ๋?
์บก์ํ(Encapsulation)๋ ์ธ๋ถ๋ก๋ถํฐ ํด๋์ค์ ์ ๋ณด๋ฅผ ๊ฐ์ถ๊ณ , ํ๋(field)์ ๋ฉ์๋(method)์ ๋ํ ๋ถํ์ํ ์ ๊ทผ์ ๋ง๋ OOP ํน์ง ์ค ํ๋์ ๋๋ค.
๐ก ์บก์ํ(Encapsulation)์ ๋ ๊ฐ์ง ์ธก๋ฉด
์บก์ํ(Encapsulation)์๋ ํฌ๊ฒ 2๊ฐ์ง ์ธก๋ฉด์ด ์์ต๋๋ค.
1. ์ธ๋ถ๋ก๋ถํฐ ํ๋(field)์ ๋ฉ์๋(method)์ ๋ํ ๋ถํ์ํ ์ ๊ทผ์ ๋ง์ต๋๋ค.
2. ์ธ๋ถ๋ก๋ถํฐ ํด๋์ค์ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ ๋ด์ฉ์ ๊ฐ์ถฅ๋๋ค.
๋จผ์ , ํ๋์ ๋ฉ์๋์ ๋ํ ๋ถํ์ํ ์ ๊ทผ์ ๋ง์์ผ ํ๋ ์ด์ ๋ฅผ ์์๋ฅผ ํตํด ์์๋ณด๊ฒ ์ต๋๋ค.
๊ฒ์ ํ์ฌ์ ๋ค๋๋ ๊ฐ๋ฐ์ A์จ๋ ์ค๋๋ ์ด๊น์์ด ํ์ฌ์ ์ถ๊ทผํ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ถ๊ทผ ๋์ฅ์ ์ฐ์๋ง์ ์ปดํจํฐ๋ฅผ ํจ A์จ๋ ํฌ๊ฒ ๋นํฉํ์๊ณ , ๋ ๋ค๋ฅธ ๊ฐ๋ฐ์ B์จ์๊ฒ ์ฐ๋ฝํฉ๋๋ค.
A์จ ํน์ ์ด์ ์ ๊ฐ ๋ง๋ Class์์ ์์ ํ ๋ด์ฉ์ด ์๋์?
B์จ ์๋์! ์ ๊ณตํด์ฃผ์ ์ฝ๋๋ฅผ ํ์ฉํ์ ๋ฟ, A์จ๊ฐ ์ ๊ณตํด์ฃผ์ ์ฝ๋๋ ์ ํ ์ฝ๋๋ฅผ ์์ ํ์ง ์์์ต๋๋ค.
A์จ๊ฐ ๊ฐ๋ฐํ ์ฌ๋ผ์ ๋ชฌ์คํฐ Class์์ ๋ฌด์ธ๊ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๋ฏํฉ๋๋ค.
์ฝ๋ ๋ฆฌ๋ทฐ ๊ณผ์ ์์ ํ์๋ค๊ณผ ๋ฌธ์ ์ ์ ํ์ ํ๊ณ ์ ์ฌ๋ผ์ Class๋ฅผ ์ดํด๋ณด์์ต๋๋ค.
public class Slime {
public String name; // ๋ชฌ์คํฐ ์ด๋ฆ
public int hp; // ๋ชฌ์คํฐ์ ์ฒด๋ ฅ
public int attackDamage; // ๊ณต๊ฒฉ๋ ฅ
public int speed; // ๋ชฌ์คํฐ์ ์๋
public Slime() {
this.name = "ํ๊ฐ ๋ ์ฌ๋ผ์";
this.hp = 100;
this.attackDamage = 10;
this.speed = 10;
}
// ์ฌ๋ผ์์ด ์ฌ์ฉ์๋ฅผ ๊ณต๊ฒฉํ๋ ๋ฉ์๋
public void attack() {
System.out.println("์ฌ๋ผ์์ด ๊ณต๊ฒฉํ์์ต๋๋ค!\n" +
"์ฒด๋ ฅ์ด " + attackDamage + " ๋งํผ ๊ฐ์ํ์์ต๋๋ค!");
}
/*
* Slime field ์ getter & setter
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
public int getAttackDamage() {
return attackDamage;
}
public void setAttackDamage(int attackDamage) {
this.attackDamage = attackDamage;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
}
์ฝ๋๊ฐ ๋ค์ ๊ธธ์ด ๋ณด์ด์ง๋ง, ์ฌ๋ผ์ class๋ ์๋์ ๊ฐ์ด ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
ํ๋(field) : '์ด๋ฆ(name)', '์ฒด๋ ฅ(hp)', '๊ณต๊ฒฉ๋ ฅ(attackDamage)', '์ด๋์๋(speed)'
๋ฉ์๋(method) : attack(), getter() & setter()
์์ธํ ์ดํด๋ณด๋ฉด, ํ๋๊ฐ ์ธ๋ถ์์ ๋ง๊ตฌ์ก์ด๋ก ์ ๊ทผํ ์ ์๋๋ก public์ผ๋ก ์ค์ ๋์ด ์์ต๋๋ค.
๊ฐ๋ฐ์ B์จ๋ ์ฌ๋ผ์์ ์ฝ๋๋ฅผ ์์ ํ์ง๋ ์์์ง๋ง, ์ธ๋ถ์์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ๊ณผ์ ์์ ๋ฏธ๋ฆฌ ์ ํด๋์ ๋ณ๊ฒฝ๋๋ฉด ์ ๋๋ ๊ฐ(field)์ ํจ๋ถ๋ก ๋ณ๊ฒฝํ์์ต๋๋ค.
๐ก ์บก์ํ(Encapsulation)๋ฅผ ์ ์ฉํ์ง ์์์ ๋์ ๋ฌธ์ ์
์ ์ฝ๋์ฒ๋ผ Class์ ์บก์ํ๋ฅผ ์ ๊ฒฝ ์ฐ์ง ์๋๋ค๋ฉด ์๋์ ๊ฐ์ ๋ฌธ์ ์ ์ด ๋ฐ์ํฉ๋๋ค.
- ํ๋(field)์ ๋ฉ์๋(method)์ ๋ถํ์ํ ์ ๊ทผ์ ์์์น ๋ชปํ ์ค๋ฅ ๋ฅผ ์ผ๊ธฐํ ์ ์์ต๋๋ค.
- Client๊ฐ ์ธ๋ถ์์ ์์ค ์ฝ๋๋ฅผ ์ฌ์ฉํ ๋, '์ ๊ทผํด๋ ๋๋ ์ ๋ณด'์ '์ ๊ทผํ์ง ์์์ผ ํ๋ ์ ๋ณด' ๋ฅผ ์ง์ ๊ตฌ๋ถํด์ผ ํ๋ค๋ ๋ถํธํจ์ด ๋ฐ์ํฉ๋๋ค.
- Client๋ ๊ตณ์ด ๋ณต์กํ ๋ด๋ถ ๋ก์ง์ ์ ํ์๊ฐ ์์ต๋๋ค. (๋๋ก๋ ๋ณต์กํ ๋ก์ง์ ๊ณต๊ฐ๊ฐ ์ฝ๋์ ์ฌ์ฉ์ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.)
- Class์ ๊ฐ์ฒด๊ฐ์ ๊ฒฐํฉ๋์ ์์กด๋๊ฐ ๋์์ง๋ฏ๋ก, ์ฝ๋์ ์ ์ง๋ณด์์ฑ์ ์ ํ์ํต๋๋ค.
๐ก ์บก์ํ(Encapsulation)๋ฅผ ์ ์ฉํ ์ฝ๋
๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ์ฝ๋๋ฅผ ์์ ํ๋ฉด ์ข์๊น์?
์บก์ํ๋ ํฌ๊ฒ 2๊ฐ์ง ํ์ ์ด ์๋ค๊ณ ์ด์ผ๊ธฐํ์ต๋๋ค.
1. ์ธ๋ถ๋ก๋ถํฐ ํ๋(field)์ ๋ฉ์๋(method)์ ๋ํ ๋ถํ์ํ ์ ๊ทผ์ ๋ง์ต๋๋ค.
2. ์ธ๋ถ๋ก๋ถํฐ ํด๋์ค์ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ ๋ด์ฉ์ ๊ฐ์ถฅ๋๋ค.
์ ์ฌ๋ก์ ๋ํด ์บก์ํ๋ฅผ ์ ์ฉํ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
public abstract class Monster {
private String name; // ๋ชฌ์คํฐ ์ด๋ฆ
private int hp; // ๋ชฌ์คํฐ์ ์ฒด๋ ฅ
private int attackDamage; // ๊ณต๊ฒฉ๋ ฅ
private int speed; // ๋ชฌ์คํฐ์ ์๋
public Monster(String name, int hp, int attackDamage, int speed) {
this.name = name;
this.hp = hp;
this.attackDamage = attackDamage;
this.speed = speed;
}
abstract void attack(); // ๋ชฌ์คํฐ๊ฐ ์ฌ์ฉ์๋ฅผ ๊ณต๊ฒฉํ๋ ๋ฉ์๋
public String getName() {
return name;
}
public int getHp() {
return hp;
}
public int getAttackDamage() {
return attackDamage;
}
public int getSpeed() {
return speed;
}
}
์ฐ์ , ์ถ์ํ ๊ฐ๋ ์ ์ ์ฉํ์ฌ ๋ชจ๋ ๋ชฌ์คํฐ๋ค์ ๊ณตํต์ ์ธ ํน์ง(name, hp, attackDamage, speed)๋ค์ ํ๋์ Monster๋ผ๋ ์ถ์ ํด๋์ค๋ก ๋ง๋ค์ด ์ฃผ์์ต๋๋ค.
public class Slime extends Monster {
public Slime() {
super("ํ๊ฐ ๋ ์ฌ๋ผ์", 100, 10, 10);
}
// ์ฌ๋ผ์์ด ์ฌ์ฉ์๋ฅผ ๊ณต๊ฒฉํ๋ ๋ฉ์๋
@Override
public void attack() {
System.out.println("์ฌ๋ผ์์ด ๊ณต๊ฒฉํ์์ต๋๋ค!\n" +
"์ฒด๋ ฅ์ด " + getAttackDamage() + " ๋งํผ ๊ฐ์ํ์์ต๋๋ค!");
}
}
Monster๋ฅผ ์์๋ฐ์ ๊ตฌํํ ์ฌ๋ผ์์ ์ฝ๋์ ๋๋ค.
์ด์ Slime์ ์ฌ์ฉํ๊ธฐ ์ํด์ ์ฌ์ฉํ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
// Before
Slime angrySlime = new Slime();
angrySlime.setAttackDamage(100000);
angrySlime.setHp(0);
// After
Monster angrySlime = new Slime();
angrySlime.setAttackDamage(100000); // ์ปดํ์ผ ์๋ฌ ๋ฐ์!!
angrySlime.setHp(0); // ์ปดํ์ผ ์๋ฌ ๋ฐ์!!
์ด์ , ์ฌ๋ผ์ Class๋ฅผ ์บก์ํํ์ฌ ๊ฐ์ ์์๋ก ๋ณ๊ฒฝํ๋ ๋ฑ ์ธ๋ถ๋ก๋ถํฐ ๋ถํ์ํ ์ ๊ทผ์ ๋ง์ ์ ์์ต๋๋ค.
Client๋ Slime์ ๋ํ ๊ตฌ์ฒด์ ์ธ ๋ก์ง์ ์ ํ์๊ฐ ์์ด์ก๊ณ , ๋จ์ํ ๊ณต๊ฒฉ(attack)ํ ์ ์๋ค๋ ์ฌ์ค๋ง ์๋ฉด ๋ฉ๋๋ค.
โญ ๊ฒฐ๋ก
์บก์ํ(Encapsulation)๋ฅผ ์ ์ฉํจ์ผ๋ก์จ
- ์ธ๋ถ๋ก๋ถํฐ ํด๋์ค์ ์ ๋ณด(field, method)์ ๋ํ ๋ถํ์ํ ์ ๊ทผ์ ๋ง๊ณ , ์์์น ๋ชปํ ์ค๋ฅ ๋ฐ์์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
- ์ธ๋ถ์ ํด๋์ค์ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ ๋ก์ง์ ๊ณต๊ฐํ์ง ์์์ผ๋ก์จ, ์ฝ๋์ ๋ณต์ก๋๋ฅผ ๋ฎ์ถ ์ ์์ต๋๋ค.
github : https://github.com/tmdgh1592