** ๐ 1๋จ๊ณ: ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ ํ์ ๋ฐฐ๊ฒฝ**
1๏ธโฃ ๊ธฐ์กด ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์(์ ์ฐจ์งํฅ ํ๋ก๊ทธ๋๋ฐ)์ ํ๊ณ
์ด๊ธฐ์ ํ๋ก๊ทธ๋๋ฐ์ ์ ์ฐจ์งํฅ ํ๋ก๊ทธ๋๋ฐ(Procedural Programming) ๋ฐฉ์์ผ๋ก ์์ฑ๋์๋ค.
์ด ๋ฐฉ์์ ๋ช ๋ น์ ์์ฐจ์ ์ผ๋ก ์คํํ๋ฉฐ ํ๋ก๊ทธ๋จ์ ๊ตฌ์ฑํ๋ ๊ตฌ์กฐ์๋ค.
๐น ์์ (์ ์ฐจ์งํฅ ๋ฐฉ์์ ํ๋ฒ๊ฑฐ ์ฃผ๋ฌธ ์ฝ๋)
print("์ฃผ๋ฌธ์ ๋ฐ์ต๋๋ค.");
print("ํ๋ฒ๊ฑฐ๋ฅผ ๋ง๋ญ๋๋ค.");
print("๊ฒฐ์ ํฉ๋๋ค.");
๐น ๋ฌธ์ ์
โ ์ฝ๋๊ฐ ๊ธธ์ด์ง๋ฉด ์ ์ง๋ณด์๊ฐ ์ด๋ ค์
โ ๋ฐ๋ณต๋๋ ์ฝ๋๊ฐ ๋ง์ ๋นํจ์จ์
โ ๋ฐ์ดํฐ์ ํจ์๊ฐ ๋ถ๋ฆฌ๋์ด ์์ด ๋ณต์กํจ
2๏ธโฃ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ ๋ฑ์ฅ
- *๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ ํ์ค ์ธ๊ณ๋ฅผ ํ๋ก๊ทธ๋๋ฐ์ผ๋ก ์ฎ๊ฒจ **๊ฐ์ฒด(์ฌ๋ฌผ)๋ค์ด ์๋ก ์ํตํ๋ ๋ฐฉ์์ ๊ตฌํํ๋ค.
์ฆ, ํ๋ก๊ทธ๋จ์ โ๋ฐ์ดํฐ + ๋์โ์ ๊ฐ์ง ๊ฐ์ฒด ๋จ์๋ก ๊ตฌ์ฑํ์ฌ, ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ด๋ ๋ฐฉ์์ด๋ค.
๐น ๊ฐ์ฒด์งํฅ ๋ฐฉ์ ์์ (ํ๋ฒ๊ฑฐ ์ฃผ๋ฌธ ์ฝ๋)
class Burger {
void makeBurger() {
System.out.println("ํ๋ฒ๊ฑฐ๋ฅผ ๋ง๋ญ๋๋ค.");
}
}
class Order {
void takeOrder() {
System.out.println("์ฃผ๋ฌธ์ ๋ฐ์ต๋๋ค.");
}
}
class Payment {
void processPayment() {
System.out.println("๊ฒฐ์ ํฉ๋๋ค.");
}
}
๐น OOP ๋ฐฉ์์ ์ฅ์
โ ์ฝ๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅ (๊ฐ์ฒดํ)
โ ์ ์ง๋ณด์๊ฐ ํธ๋ฆฌํจ (๋ชจ๋ํ)
โ ํ์ฅ์ฑ์ด ๋ฐ์ด๋จ (์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ ์ฉ์ด)
3๏ธโฃ OOP์ ๋ฐ์ ๊ณผ์
โ 1960๋ ๋: ์ต์ด์ ๊ฐ์ฒด์งํฅ ์ธ์ด Simula ๋ฑ์ฅ
โ 1980๋ ๋: C++ ๋ฑ์ฅ, ๊ฐ์ฒด์งํฅ ๊ฐ๋ ์ด ๋ณธ๊ฒฉ์ ์ผ๋ก ๋์
โ 1995๋ : Java ํ์, ์น๊ณผ ํจ๊ป ๋์คํ
โ 2000๋ ๋ ์ดํ: Python, C#, Kotlin, Swift ๋ฑ ๋ค์ํ ๊ฐ์ฒด์งํฅ ์ธ์ด ๋ฑ์ฅ
๐ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ํํธ์จ์ด ๊ฐ๋ฐ์ ๋ ์ฝ๊ณ , ํจ์จ์ ์ผ๋ก ๋ง๋ค๊ธฐ ์ํด ๋ฑ์ฅํ ํ์ ์ ์ธ ๊ฐ๋ ์ด๋ค! ๐
๐ 2๋จ๊ณ: ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ 4๊ฐ์ง ํต์ฌ ์์น
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ 4๊ฐ์ง ํต์ฌ ์์น์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ค.
์ด ์์น๋ค์ ์ ์ง๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ์ ๋์ด๊ณ , ๋ณด๋ค ์์ ์ ์ธ ํ๋ก๊ทธ๋จ์ ๋ง๋๋ ๋ฐ ๋์์ ์ค๋ค.
1๏ธโฃ ์บก์ํ(Encapsulation) - โ๋ฐ์ดํฐ ๋ณดํธ & ์ ๊ทผ ์ ํโ
๐ ๊ฐ๋
์บก์ํ๋ ๊ฐ์ฒด์ ๋ด๋ถ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๊ณ , ์ธ๋ถ์์๋ ์ ํ๋ ๋ฐฉ์์ผ๋ก๋ง ์ ๊ทผํ๋๋ก ๋ง๋๋ ๊ธฐ์ ์ด๋ค.
์ฆ, ๋ฐ์ดํฐ์ ๊ธฐ๋ฅ(๋ฉ์๋)์ ํ๋์ ๊ฐ์ฒด๋ก ๋ฌถ๊ณ , ์ธ๋ถ์์ ์ง์ ์ ๊ทผ์ ์ฐจ๋จํ๋ ๊ฐ๋ ์ด๋ค.
โ ๏ธ ์ ํ์ํ ๊น?
โ ์๋ชป๋ ๋ฐ์ดํฐ ์์ ๋ฐฉ์ง (์: ์ฒด๋ ฅ์ด -100์ด ๋๋ ๋ฌธ์ )
โ ์ฝ๋์ ๋ณต์ก์ฑ์ ์ค์ด๊ณ , ์ ์ง๋ณด์์ฑ์ ๋์
โ ๋ณด์ ๊ฐํ (์ค์ํ ๋ฐ์ดํฐ๊ฐ ์ธ๋ถ์์ ์ง์ ์์ ๋์ง ์์)
๐ ์์ ์ฝ๋ (์บก์ํ๋ฅผ ์ฌ์ฉํ ๊ฒ์ ์บ๋ฆญํฐ)
class Player {
private int hp = 100; // ์ฒด๋ ฅ์ ์ธ๋ถ์์ ์ง์ ๋ณ๊ฒฝ ๋ถ๊ฐ
public int getHp() { // ์ฒด๋ ฅ ์กฐํ (์ฝ๊ธฐ ๊ฐ๋ฅ)
return hp;
}
public void takeDamage(int damage) { // ์ฒด๋ ฅ ๊ฐ์ (์ฐ๊ธฐ ๊ฐ๋ฅ)
if (damage > 0) {
hp -= damage;
if (hp < 0) hp = 0; // ์ฒด๋ ฅ์ด 0 ์ดํ๋ก ๋ด๋ ค๊ฐ์ง ์๋๋ก ์ค์
}
}
}
โ private
ํค์๋๋ก ๋ณ์ hp
๋ฅผ ์จ๊น
โ public
๋ฉ์๋(getHp()
, takeDamage()
)๋ฅผ ํตํด ๊ฐ์ ์ ์ผ๋ก ์ ๊ทผ
2๏ธโฃ ์์(Inheritance) - โ์ฝ๋ ์ฌ์ฌ์ฉโ
๐ ๊ฐ๋
์์์ ๊ธฐ์กด ํด๋์ค(๋ถ๋ชจ)์ ๊ธฐ๋ฅ์ ๋ฌผ๋ ค๋ฐ์ ์๋ก์ด ํด๋์ค(์์)๋ฅผ ๋ง๋๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ฆ, ๊ณตํต๋ ๊ธฐ๋ฅ์ ๋ถ๋ชจ ํด๋์ค์ ์ ์ํ๊ณ , ์ด๋ฅผ ์์ ํด๋์ค๊ฐ ์ฌ์ฌ์ฉํ๋ ๋ฐฉ์์ด๋ค.
โ ๏ธ ์ ํ์ํ ๊น?
โ ์ค๋ณต ์ฝ๋ ์ ๊ฑฐ
โ ์ฝ๋ ์ ์ง๋ณด์ ์ฉ์ด
โ ์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ๊ฐ ์ฌ์
๐ ์์ ์ฝ๋ (๋๋ฌผ ํด๋์ค ์์)
class Animal { // ๋ถ๋ชจ ํด๋์ค
void eat() {
System.out.println("๋จน๋๋ค!");
}
}
// ๐ ๊ฐ์์ง ํด๋์ค (Animal์ ๋ฌผ๋ ค๋ฐ์)
class Dog extends Animal {
void bark() {
System.out.println("๋ฉ๋ฉ!");
}
}
// ๐ฑ ๊ณ ์์ด ํด๋์ค (Animal์ ๋ฌผ๋ ค๋ฐ์)
class Cat extends Animal {
void meow() {
System.out.println("์ผ์น!");
}
}
โ Dog
์ Cat
์ Animal
์ eat()
๋ฉ์๋๋ฅผ ์์๋ฐ์ ์ฌ์ฉ ๊ฐ๋ฅ
โ ๊ฐ ํด๋์ค์์ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ(bark()
, meow()
)์ ์ ์
3๏ธโฃ ๋คํ์ฑ(Polymorphism) - โํ๋์ ์ธํฐํ์ด์ค, ๋ค์ํ ๊ตฌํโ
๐ ๊ฐ๋
๋คํ์ฑ์ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ฌ๋ฌ ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ ์๋๋ก ํ๋ ๊ธฐ์ ์ด๋ค.
์ฆ, ํ๋์ ์ฝ๋๋ก ๋ค์ํ ๋์์ ํ ์ ์๋๋ก ๋ง๋ ๋ค.
โ ๏ธ ์ ํ์ํ ๊น?
โ ์ ์ฐํ ์ฝ๋ ์์ฑ ๊ฐ๋ฅ
โ ํ์ฅ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ๋ฐ์ด๋จ
โ ๊ฐ์ ์ธํฐํ์ด์ค๋ก ์ฌ๋ฌ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋ค๋ฃฐ ์ ์์
๐ ์์ ์ฝ๋ (์ค๋ฒ๋ผ์ด๋ฉ์ ์ด์ฉํ ๋คํ์ฑ)
class Animal {
void speak() {
System.out.println("๋๋ฌผ์ด ์๋ฆฌ๋ฅผ ๋ธ๋ค!");
}
}
class Dog extends Animal {
@Override
void speak() {
System.out.println("๋ฉ๋ฉ!");
}
}
class Cat extends Animal {
@Override
void speak() {
System.out.println("์ผ์น!");
}
}
public class Test {
public static void main(String[] args) {
Animal myPet = new Dog();
myPet.speak(); // "๋ฉ๋ฉ!" ์ถ๋ ฅ
myPet = new Cat();
myPet.speak(); // "์ผ์น!" ์ถ๋ ฅ
}
}
โ ๋ถ๋ชจ ํด๋์ค Animal
์ speak()
๋ฉ์๋๋ฅผ Dog
์ Cat
์์ ๊ฐ๊ฐ ๋ค๋ฅด๊ฒ ๊ตฌํ(์ค๋ฒ๋ผ์ด๋ฉ)
โ ๊ฐ์ Animal
ํ์
์ด์ง๋ง speak()
๊ฐ ์คํ๋ ๋ ๋ค๋ฅด๊ฒ ๋์ (๋คํ์ฑ ๊ตฌํ)
4๏ธโฃ ์ถ์ํ(Abstraction) - โํ์ํ ๊ธฐ๋ฅ๋ง ๋ ธ์ถโ
๐ ๊ฐ๋
์ถ์ํ๋ ๋ถํ์ํ ์ธ๋ถ ์ฌํญ์ ์จ๊ธฐ๊ณ , ์ค์ํ ๊ธฐ๋ฅ๋ง ์ธ๋ถ์ ์ ๊ณตํ๋ ๊ฐ๋ ์ด๋ค.
์ฆ, ๊ฐ์ฒด์ ๋ด๋ถ ๊ตฌํ์ ๊ฐ์ถ๊ณ , ํต์ฌ ๊ธฐ๋ฅ๋ง ์ ์ํ๋ ๊ฒ์ด๋ค.
โ ๏ธ ์ ํ์ํ ๊น?
โ ๋ณต์กํ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ์จ๊ธฐ๊ณ ๊ฐ๋จํ ์ธํฐํ์ด์ค๋ง ์ ๊ณต
โ ์ ์ง๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ์ด ๋ฐ์ด๋จ
โ ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ฌ์ฌ์ฉ์ฑ์ด ์ฆ๊ฐ
๐ ์์ ์ฝ๋ (์ถ์ ํด๋์ค๋ฅผ ํ์ฉํ ์ถ์ํ)
abstract class Car {
abstract void drive(); // ๐ "์ด์ ํ๋ ๋ฐฉ๋ฒ"๋ง ์ ํจ (๊ตฌํ X)
public void stop() {
System.out.println("์๋์ฐจ๊ฐ ๋ฉ์ถ๋ค.");
}
}
class Tesla extends Car {
@Override
void drive() {
System.out.println("์ ๊ธฐ์ฐจ๋ก ์์จ์ฃผํ!");
}
}
class Ferrari extends Car {
@Override
void drive() {
System.out.println("V12 ์์ง์ผ๋ก ๋น ๋ฅด๊ฒ ๋ฌ๋ฆฐ๋ค!");
}
}
โ Car
ํด๋์ค์์ drive()
๋ฅผ ์ถ์ ๋ฉ์๋๋ก ์ ์ธ (๊ตฌ์ฒด์ ์ธ ๊ตฌํ X)
โ ๊ฐ ์์ ํด๋์ค(Tesla
, Ferrari
)์์ drive()
์ ๊ตฌ์ฒด์ ์ธ ๋์์ ๊ตฌํ
๐ฏ 2๋จ๊ณ ์์ฝ
OOP ์์น | ์ค๋ช | ์ฅ์ |
---|---|---|
์บก์ํ | ๋ฐ์ดํฐ๋ฅผ ์จ๊ธฐ๊ณ , ๋ฉ์๋๋ฅผ ํตํด ์ ๊ทผํ๋๋ก ์ ํ | ๋ฐ์ดํฐ ๋ณดํธ, ์ ์ง๋ณด์ ์ฉ์ด |
์์ | ๊ธฐ์กด ํด๋์ค์ ๊ธฐ๋ฅ์ ๋ฌผ๋ ค๋ฐ์ ์ฌ์ฌ์ฉ | ์ฝ๋ ์ค๋ณต ์ ๊ฑฐ, ํ์ฅ ์ฉ์ด |
๋คํ์ฑ | ๊ฐ์ ๋ฉ์๋๋ฅผ ๋ค์ํ ๋ฐฉ์์ผ๋ก ๊ตฌํ ๊ฐ๋ฅ | ์ ์ฐํ ์ฝ๋, ์ ์ง๋ณด์์ฑ ํฅ์ |
์ถ์ํ | ๋ด๋ถ ๊ตฌํ์ ๊ฐ์ถ๊ณ , ํต์ฌ ๊ธฐ๋ฅ๋ง ์ ๊ณต | ๋ณต์ก์ฑ ๊ฐ์, ์ธํฐํ์ด์ค ๋จ์ํ |
๐ 3๋จ๊ณ: ํด๋์ค์ ๊ฐ์ฒด - ์ค๊ณ๋์ ์ค์ฒด
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ ํต์ฌ ๊ฐ๋ ์ ํด๋์ค(Class)์ ๊ฐ์ฒด(Object) ์ด๋ค.
ํด๋์ค๋ ์ค๊ณ๋(์ฒญ์ฌ์ง) ์ญํ ์ ํ๊ณ , ๊ฐ์ฒด๋ ํด๋์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ๋ ์ค์ฒด(Instance) ์ด๋ค.
1๏ธโฃ ํด๋์ค(Class)๋? - ์ค๊ณ๋
ํด๋์ค๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํ ํ(ํ ํ๋ฆฟ, ์ค๊ณ๋) ์ด๋ค.
์ฆ, ๊ฐ์ฒด๊ฐ ์ด๋ค ์์ฑ(๋ณ์)๊ณผ ๋์(๋ฉ์๋)์ ๊ฐ์ง์ง ์ ์ํ๋ ์ญํ ์ ํ๋ค.
๐ ์์ ์ฝ๋ (์๋์ฐจ ํด๋์ค)
class Car {
String color; // ์์ฑ (๋ณ์)
int speed; // ์์ฑ (๋ณ์)
void drive() { // ๋์ (๋ฉ์๋)
System.out.println("์๋์ฐจ๊ฐ ๋ฌ๋ฆฝ๋๋ค!");
}
void stop() { // ๋์ (๋ฉ์๋)
System.out.println("์๋์ฐจ๊ฐ ๋ฉ์ถฅ๋๋ค!");
}
}
โ Car
ํด๋์ค๋ ์๋์ฐจ์ ์์ฑ(color
, speed
)๊ณผ ๋์(drive()
, stop()
)์ ์ ์
โ ์ด์ Car
ํด๋์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ค์ ์๋์ฐจ(๊ฐ์ฒด)๋ฅผ ์์ฑํ ์ ์์
2๏ธโฃ ๊ฐ์ฒด(Object)๋? - ์ค๊ณ๋๋ก ๋ง๋ ์ค์ฒด
๊ฐ์ฒด๋ ํด๋์ค(์ค๊ณ๋)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ๋ ์ค์ฒด ์ด๋ค.
์ฆ, ํด๋์ค์์ ์ ์ํ ์์ฑ๊ณผ ๋์์ ์ค์ ๋ก ์ํํ ์ ์๋ ์กด์ฌ์ด๋ค.
๐ ๊ฐ์ฒด ์์ฑ ๋ฐ ์ฌ์ฉ ์์
public class Main {
public static void main(String[] args) {
Car myCar = new Car(); // ๊ฐ์ฒด ์์ฑ
myCar.color = "๋นจ๊ฐ"; // ์์ฑ ์ค์
myCar.speed = 100;
myCar.drive(); // ์๋์ฐจ๊ฐ ๋ฌ๋ฆฝ๋๋ค!
System.out.println("์์: " + myCar.color); // ์์: ๋นจ๊ฐ
}
}
โ Car myCar = new Car();
โ Car
ํด๋์ค ๊ธฐ๋ฐ์ผ๋ก myCar
๊ฐ์ฒด ์์ฑ
โ ๊ฐ์ฒด์ ์์ฑ์ ์ค์ ํ๊ณ (myCar.color = "๋นจ๊ฐ";
) ๋์์ ์คํ (myCar.drive();
)
3๏ธโฃ ์์ฑ์(Constructor) - ๊ฐ์ฒด ์ด๊ธฐํ ๋ด๋น
์์ฑ์๋ ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ์๋์ผ๋ก ํธ์ถ๋๋ ํน์ํ ๋ฉ์๋ ์ด๋ค.
์ฃผ๋ก ๊ฐ์ฒด์ ์์ฑ์ ์ด๊ธฐํํ๋ ์ญํ ์ ํ๋ค.
๐ ์์ฑ์ ์ฌ์ฉ ์์
class Car {
String color;
int speed;
// ์์ฑ์ ์ ์
Car(String color, int speed) {
this.color = color;
this.speed = speed;
}
void drive() {
System.out.println(color + " ์๋์ฐจ๊ฐ " + speed + "km/h๋ก ๋ฌ๋ฆฝ๋๋ค!");
}
}
public class Main {
public static void main(String[] args) {
Car myCar = new Car("ํ๋์", 120); // ๊ฐ์ฒด ์์ฑ ์ ์๋์ผ๋ก ์ด๊ธฐํ
myCar.drive(); // ํ๋์ ์๋์ฐจ๊ฐ 120km/h๋ก ๋ฌ๋ฆฝ๋๋ค!
}
}
โ Car(String color, int speed)
โ ์์ฑ์์์ ์์ฑ์ ์ด๊ธฐํ
โ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ๊ฐ("ํ๋์"
, 120
)์ ์ ๋ฌํ์ฌ ์๋ ์ค์ ๊ฐ๋ฅ
๐ฏ 3๋จ๊ณ ์์ฝ
๊ฐ๋ | ์ค๋ช | ์์ |
---|---|---|
ํด๋์ค(Class) | ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ค๊ณ๋ | class Car { String color; void drive() {} } |
๊ฐ์ฒด(Object) | ํด๋์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ๋ ์ค์ฒด | Car myCar = new Car(); |
์์ฑ์(Constructor) | ๊ฐ์ฒด ์์ฑ ์ ์๋ ํธ์ถ๋๋ ์ด๊ธฐํ ๋ฉ์๋ | Car(String color) { this.color = color; } |
โก๏ธ ํด๋์ค(์ค๊ณ๋)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ์ฒด(์ค์ฒด)๋ฅผ ๋ง๋ค๊ณ , ์์ฑ์๋ฅผ ํ์ฉํ๋ฉด ๋ ํธ๋ฆฌํ ์ด๊ธฐํ๊ฐ ๊ฐ๋ฅํ๋ค! ๐
๐ 4๋จ๊ณ: ์ ๊ทผ ์ ์ด์ & ๋ฉ์๋ ์ค๋ฒ๋ก๋ฉ
1๏ธโฃ ์ ๊ทผ ์ ์ด์(Access Modifier) - ๋ฐ์ดํฐ ๋ณดํธ
์ ๊ทผ ์ ์ด์๋ ํด๋์ค์ ๋ณ์(ํ๋)๋ ๋ฉ์๋์ ์ ๊ทผํ ์ ์๋ ๋ฒ์๋ฅผ ์ ํํ๋ ํค์๋์ด๋ค.
์ฆ, ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๊ณ , ๋ถํ์ํ ์ ๊ทผ์ ์ฐจ๋จํ๋ ์ญํ ์ ํ๋ค.
๐น ์ ๊ทผ ์ ์ด์์ ์ข ๋ฅ
์ ๊ทผ ์ ์ด์ | ๊ฐ์ ํด๋์ค | ๊ฐ์ ํจํค์ง | ์์ ๊ด๊ณ(๋ค๋ฅธ ํจํค์ง) | ๋ค๋ฅธ ํจํค์ง |
---|---|---|---|---|
public |
โ | โ | โ | โ |
protected |
โ | โ | โ | โ |
default (์๋ฌด๊ฒ๋ ์ ์) |
โ | โ | โ | โ |
private |
โ | โ | โ | โ |
โ public
โ ์ด๋์๋ ์ ๊ทผ ๊ฐ๋ฅ
โ protected
โ ๊ฐ์ ํจํค์ง ๋๋ ์์๋ฐ์ ํด๋์ค์์๋ง ์ ๊ทผ ๊ฐ๋ฅ
โ default
โ ๊ฐ์ ํจํค์ง์์๋ง ์ ๊ทผ ๊ฐ๋ฅ (์๋ฌด๊ฒ๋ ์ ์ฐ๋ฉด ๊ธฐ๋ณธ๊ฐ)
โ private
โ ๊ฐ์ ํด๋์ค ๋ด๋ถ์์๋ง ์ ๊ทผ ๊ฐ๋ฅ
๐น ์์ : ์ ๊ทผ ์ ์ด์ ์ ์ฉํ๊ธฐ
class BankAccount {
private int balance = 1000; // `private` -> ์ธ๋ถ์์ ์ง์ ์ ๊ทผ ๋ถ๊ฐ
// Getter ๋ฉ์๋ (์ฝ๊ธฐ ๊ฐ๋ฅ)
public int getBalance() {
return balance;
}
// Setter ๋ฉ์๋ (์ฐ๊ธฐ ๊ฐ๋ฅ)
public void deposit(int amount) {
if (amount > 0) {
balance += amount;
}
}
}
public class Main {
public static void main(String[] args) {
BankAccount account = new BankAccount();
// ์ง์ ์ ๊ทผ ๋ถ๊ฐ (์ค๋ฅ ๋ฐ์)
// account.balance = 5000;
account.deposit(500); // 500์ ์
๊ธ
System.out.println("์์ก: " + account.getBalance()); // ์์ก: 1500
}
}
โ private
๋ก balance๋ฅผ ์จ๊ฒจ ์ธ๋ถ์์ ์ง์ ์์ ๋ถ๊ฐ๋ฅ
โ public
๋ฉ์๋(deposit()
๊ณผ getBalance()
)๋ฅผ ํตํด์๋ง ์ ๊ทผ ๊ฐ๋ฅ
2๏ธโฃ ๋ฉ์๋ ์ค๋ฒ๋ก๋ฉ(Method Overloading) - ๊ฐ์ ์ด๋ฆ, ๋ค๋ฅธ ๋งค๊ฐ๋ณ์
๋ฉ์๋ ์ค๋ฒ๋ก๋ฉ์ ๊ฐ์ ์ด๋ฆ์ ๋ฉ์๋๋ฅผ ๋งค๊ฐ๋ณ์(ํ๋ผ๋ฏธํฐ)๋ฅผ ๋ค๋ฅด๊ฒ ํ์ฌ ์ฌ๋ฌ ๊ฐ ์ ์ํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ฆ, ๊ฐ์ ๊ธฐ๋ฅ์ ์ํํ์ง๋ง, ์ ๋ ฅ๊ฐ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋์์ ํ ์ ์๋๋ก ํ๋ ๊ธฐ๋ฅ์ด๋ค.
๐น ๋ฉ์๋ ์ค๋ฒ๋ก๋ฉ ์์
class MathUtil {
// ์ ์ ๋ง์
int add(int a, int b) {
return a + b;
}
// ์ค์ ๋ง์
(์ค๋ฒ๋ก๋ฉ)
double add(double a, double b) {
return a + b;
}
// ์ธ ๊ฐ์ ์ซ์๋ฅผ ๋ํ๋ ๋ฉ์๋ (์ค๋ฒ๋ก๋ฉ)
int add(int a, int b, int c) {
return a + b + c;
}
}
public class Main {
public static void main(String[] args) {
MathUtil calc = new MathUtil();
System.out.println(calc.add(2, 3)); // 5
System.out.println(calc.add(2.5, 3.2)); // 5.7
System.out.println(calc.add(1, 2, 3)); // 6
}
}
โ add()
๋ฉ์๋๋ฅผ ๋ค์ํ ๋งค๊ฐ๋ณ์๋ก ์ ์ํ์ฌ ์ค๋ฒ๋ก๋ฉ ๊ตฌํ
โ ์ ์, ์ค์, 3๊ฐ์ ์ซ์๋ฅผ ๋ํ ๋ ๊ฐ์ add()
๋ฉ์๋๋ฅผ ์ฌ์ฉ ๊ฐ๋ฅ
๐ฏ 4๋จ๊ณ ์์ฝ
๊ฐ๋ | ์ค๋ช | ์์ |
---|---|---|
์ ๊ทผ ์ ์ด์ | ํด๋์ค ๋ฉค๋ฒ(๋ณ์, ๋ฉ์๋)์ ๋ํ ์ ๊ทผ ๋ฒ์๋ฅผ ์ ํ | private int balance; |
public | ์ด๋์๋ ์ ๊ทผ ๊ฐ๋ฅ | public void deposit() {} |
protected | ๊ฐ์ ํจํค์ง & ์์ ๊ด๊ณ์์ ์ ๊ทผ ๊ฐ๋ฅ | protected int age; |
default | ๊ฐ์ ํจํค์ง์์๋ง ์ ๊ทผ ๊ฐ๋ฅ | int score; |
private | ๊ฐ์ ํด๋์ค์์๋ง ์ ๊ทผ ๊ฐ๋ฅ | private String password; |
๋ฉ์๋ ์ค๋ฒ๋ก๋ฉ | ๊ฐ์ ์ด๋ฆ์ ๋ฉ์๋๋ฅผ ๋งค๊ฐ๋ณ์์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ ์ | int add(int a, int b) / double add(double a, double b) |
โก๏ธ ์ ๊ทผ ์ ์ด์๋ฅผ ํ์ฉํ๋ฉด ๋ฐ์ดํฐ ๋ณดํธ๊ฐ ๊ฐ๋ฅํ๊ณ , ๋ฉ์๋ ์ค๋ฒ๋ก๋ฉ์ ํ์ฉํ๋ฉด ์ฝ๋์ ์ ์ฐ์ฑ์ด ์ฆ๊ฐํ๋ค! ๐
๐ 5๋จ๊ณ: ์์(Inheritance)๊ณผ ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ(Overriding)
์์๊ณผ ์ค๋ฒ๋ผ์ด๋ฉ์ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ผ๋ก, ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ฐ์ฑ์ ๊ทน๋ํํ๋ ๋ฐ ๋์์ ์ค๋ค.
1๏ธโฃ ์์(Inheritance) - ๋ถ๋ชจ ํด๋์ค๋ฅผ ํ์ฅํ์ฌ ์ฌ์ฌ์ฉ
์์์ ๊ธฐ์กด ํด๋์ค(๋ถ๋ชจ)์ ๊ธฐ๋ฅ์ ๋ฌผ๋ ค๋ฐ์ ์๋ก์ด ํด๋์ค(์์)๋ฅผ ๋ง๋๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ฆ, ๊ณตํต๋ ๊ธฐ๋ฅ์ ๋ถ๋ชจ ํด๋์ค์ ์ ์ํ๊ณ , ์ด๋ฅผ ์์ ํด๋์ค๊ฐ ์ฌ์ฌ์ฉํ๋ ๋ฐฉ์์ด๋ค.
๐น ์์์ ์ฅ์
โ ์ฝ๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅ โ ์ค๋ณต ์ฝ๋ ์ต์ํ
โ ์ ์ง๋ณด์ ์ฉ์ด โ ๋ถ๋ชจ ํด๋์ค ์์ ์, ์์ ํด๋์ค์๋ ์๋ ๋ฐ์
โ ๊ธฐ๋ฅ ํ์ฅ ๊ฐ๋ฅ โ ๋ถ๋ชจ์ ๊ธฐ๋ฅ์ ๊ธฐ๋ฐ์ผ๋ก ์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ ๊ฐ๋ฅ
๐น ์์ : ๋๋ฌผ ํด๋์ค๋ฅผ ์์ํ ๊ฐ์ ๊ณ ์์ด
class Animal { // ๋ถ๋ชจ ํด๋์ค
void eat() {
System.out.println("๋จน๋๋ค!");
}
}
// ๐ ๊ฐ ํด๋์ค (Animal์ ์์๋ฐ์)
class Dog extends Animal {
void bark() {
System.out.println("๋ฉ๋ฉ!");
}
}
// ๐ฑ ๊ณ ์์ด ํด๋์ค (Animal์ ์์๋ฐ์)
class Cat extends Animal {
void meow() {
System.out.println("์ผ์น!");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat(); // ๋ถ๋ชจ ํด๋์ค ๊ธฐ๋ฅ ์ฌ์ฉ ("๋จน๋๋ค!")
myDog.bark(); // ๊ฐ ํด๋์ค ๊ธฐ๋ฅ ์ฌ์ฉ ("๋ฉ๋ฉ!")
Cat myCat = new Cat();
myCat.eat(); // ๋ถ๋ชจ ํด๋์ค ๊ธฐ๋ฅ ์ฌ์ฉ ("๋จน๋๋ค!")
myCat.meow(); // ๊ณ ์์ด ํด๋์ค ๊ธฐ๋ฅ ์ฌ์ฉ ("์ผ์น!")
}
}
โ Dog
์ Cat
์ Animal
์ eat()
๋ฉ์๋๋ฅผ ์์๋ฐ์ ์ฌ์ฉ ๊ฐ๋ฅ
โ ๊ฐ ํด๋์ค์์ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ(bark()
, meow()
)์ ์ ์
2๏ธโฃ ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ(Method Overriding) - ๋ถ๋ชจ ๋ฉ์๋ ์ฌ์ ์
๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ์ ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋๋ฅผ ์์ ํด๋์ค์์ ์ฌ์ ์(๋ณ๊ฒฝ)ํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ฆ, ๋ถ๋ชจ ํด๋์ค์์ ์ ๊ณตํ ๊ธฐ๋ณธ ๋์์ ์์ ํด๋์ค์์ ๋ณ๊ฒฝํ ์ ์๋๋ก ํ๋ ๊ธฐ๋ฅ์ด๋ค.
๐น ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ์ ๊ท์น
โ ๋ฉ์๋ ์ด๋ฆ, ๋ฐํ ํ์ , ๋งค๊ฐ๋ณ์๊ฐ ๋์ผํด์ผ ํจ
โ ์ ๊ทผ ์ ์ด์๋ ๋ถ๋ชจ ๋ฉ์๋๋ณด๋ค ๋ ์ข์ ๋ฒ์๋ก ์ค์ ํ ์ ์์
โ ๋ถ๋ชจ ๋ฉ์๋๋ณด๋ค ๋ ๋์ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ผ ํจ
๐น ์์ : ๋๋ฌผ ์๋ฆฌ ์ฌ์ ์ํ๊ธฐ (์ค๋ฒ๋ผ์ด๋ฉ ์ ์ฉ)
class Animal {
void speak() {
System.out.println("๋๋ฌผ์ด ์๋ฆฌ๋ฅผ ๋ธ๋ค!");
}
}
// ๐ ๊ฐ ํด๋์ค (Animal์ ์์๋ฐ์)
class Dog extends Animal {
@Override // ๋ถ๋ชจ์ speak() ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ
void speak() {
System.out.println("๋ฉ๋ฉ!");
}
}
// ๐ฑ ๊ณ ์์ด ํด๋์ค (Animal์ ์์๋ฐ์)
class Cat extends Animal {
@Override
void speak() {
System.out.println("์ผ์น!");
}
}
public class Main {
public static void main(String[] args) {
Animal myPet = new Dog();
myPet.speak(); // "๋ฉ๋ฉ!" (์ค๋ฒ๋ผ์ด๋ฉ๋ ๋ฉ์๋ ์คํ)
myPet = new Cat();
myPet.speak(); // "์ผ์น!" (์ค๋ฒ๋ผ์ด๋ฉ๋ ๋ฉ์๋ ์คํ)
}
}
โ ๋ถ๋ชจ ํด๋์ค Animal
์ speak()
๋ฉ์๋๋ฅผ Dog
์ Cat
์์ ๊ฐ๊ฐ ๋ค๋ฅด๊ฒ ๊ตฌํ (์ค๋ฒ๋ผ์ด๋ฉ)
โ ๊ฐ์ Animal
ํ์
์ด์ง๋ง speak()
์คํ ์ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅด๊ฒ ์ถ๋ ฅ๋จ (๋คํ์ฑ ํ์ฉ)
3๏ธโฃ super
ํค์๋ - ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋ ํธ์ถ
์ค๋ฒ๋ผ์ด๋ฉํ ๋ฉ์๋์์ ๋ถ๋ชจ ํด๋์ค์ ์๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ณ ์ถ์ ๋ super
ํค์๋๋ฅผ ์ฌ์ฉํ๋ค.
๐น ์์ : super
ํค์๋ ์ฌ์ฉํ๊ธฐ
class Animal {
void speak() {
System.out.println("๋๋ฌผ์ด ์๋ฆฌ๋ฅผ ๋ธ๋ค!");
}
}
class Dog extends Animal {
@Override
void speak() {
super.speak(); // ๋ถ๋ชจ ํด๋์ค์ speak() ์คํ
System.out.println("๋ฉ๋ฉ!"); // ์ถ๊ฐ ๊ธฐ๋ฅ
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.speak();
}
}
์ถ๋ ฅ ๊ฒฐ๊ณผ:
๋๋ฌผ์ด ์๋ฆฌ๋ฅผ ๋ธ๋ค!
๋ฉ๋ฉ!
โ super.speak();
์ ์ฌ์ฉํด ๋ถ๋ชจ ํด๋์ค์ speak()
๋ฅผ ๋จผ์ ์คํํ ํ, ์ถ๊ฐ ๊ธฐ๋ฅ ์ํ
4๏ธโฃ ๋ค์ค ์์ ๋ฌธ์ - Java์์ ์ธํฐํ์ด์ค ํ์ฉ
์๋ฐ์์๋ ๋ค์ค ์์(์ฌ๋ฌ ๋ถ๋ชจ ํด๋์ค๋ฅผ ๋์์ ์์)์ ํ์ฉํ์ง ์๋๋ค.
์ด์ :
โ ๋ ๋ถ๋ชจ ํด๋์ค์ ๊ฐ์ ์ด๋ฆ์ ๋ฉ์๋๊ฐ ์์ผ๋ฉด ์ถฉ๋ ๊ฐ๋ฅ
โ ์ฝ๋๊ฐ ๋ณต์กํด์ง๊ณ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์
ํ์ง๋ง ์ธํฐํ์ด์ค(interface) ๋ฅผ ํ์ฉํ๋ฉด ๋ค์ค ์์๊ณผ ์ ์ฌํ ํจ๊ณผ๋ฅผ ๋ผ ์ ์๋ค.
(์ธํฐํ์ด์ค๋ ๋ค์ ๋จ๊ณ์์ ์์ธํ ์ค๋ช !)
๐ฏ 5๋จ๊ณ ์์ฝ
๊ฐ๋ | ์ค๋ช | ์์ |
---|---|---|
์์(Inheritance) | ๋ถ๋ชจ ํด๋์ค์ ๊ธฐ๋ฅ์ ๋ฌผ๋ ค๋ฐ์ ์ฝ๋ ์ฌ์ฌ์ฉ | class Dog extends Animal {} |
์ค๋ฒ๋ผ์ด๋ฉ(Overriding) | ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋๋ฅผ ์์ ํด๋์ค์์ ์ฌ์ ์ | @Override void speak() {} |
super ํค์๋ | ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ์ฌ์ฉ | super.speak(); |
๋ค์ค ์์ ๋ฌธ์ | ์๋ฐ์์๋ ๋ค์ค ์์์ ์ง์ํ์ง ์์ | ์ธํฐํ์ด์ค๋ก ํด๊ฒฐ ๊ฐ๋ฅ |
โก๏ธ ์์์ ํ์ฉํ๋ฉด ์ฝ๋ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ณ , ์ค๋ฒ๋ผ์ด๋ฉ์ ํตํด ์ ์ฐํ ์ฝ๋ ํ์ฅ์ด ๊ฐ๋ฅํ๋ค! ๐
๐ 6๋จ๊ณ: ์ธํฐํ์ด์ค(Interface)์ ์ถ์ ํด๋์ค(Abstract Class)
์๋ฐ์์๋ ๋ค์ค ์์์ ์ง์ํ์ง ์์ง๋ง, ์ธํฐํ์ด์ค(Interface)์ ์ถ์ ํด๋์ค(Abstract Class) ๋ฅผ ํ์ฉํ๋ฉด ์ ์ฐํ ์ค๊ณ๊ฐ ๊ฐ๋ฅํ๋ค.
์ด ๋ ๊ฐ๋ ์ ๊ฐ์ฒด์งํฅ ์ค๊ณ ์์น(SOLID) ์ค ๊ฐ๋ฐฉ-ํ์ ์์น(Open-Closed Principle)์ ๋ฐ๋ฅด๋ฉฐ, ์ ์ง๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ์ ๋์ด๋ ํต์ฌ ์์์ด๋ค.
1๏ธโฃ ์ถ์ ํด๋์ค(Abstract Class) - โ๊ณตํต์ ์ธ ํน์ง์ ์ ์โ
์ถ์ ํด๋์ค๋ ์ผ๋ฐ ํด๋์ค์ ์ธํฐํ์ด์ค์ ์ค๊ฐ ํํ๋ก, ์ผ๋ถ๋ ๊ตฌํํ๊ณ ์ผ๋ถ๋ ๊ตฌํํ์ง ์๋ ํด๋์ค์ด๋ค.
์ฆ, ์ถ์ ํด๋์ค ์์ฒด๋ก๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๊ณ , ์์๋ฐ์ ์์ ํด๋์ค๊ฐ ๊ตฌํํด์ผ ํ๋ ํ์ ๋ฉ์๋๋ฅผ ์ ์ํ ์ ์๋ค.
๐น ์ถ์ ํด๋์ค์ ํน์ง
โ abstract
ํค์๋๋ฅผ ์ฌ์ฉํด ์ ์ธ
โ ์ผ๋ถ ๋ฉ์๋๋ ๊ตฌํ ๊ฐ๋ฅ, ์ผ๋ถ๋ ๊ฐ์ ์ ์ผ๋ก ๊ตฌํํ๋๋ก ์ค์ ๊ฐ๋ฅ (abstract
๋ฉ์๋)
โ ๊ฐ์ฒด๋ฅผ ์ง์ ์์ฑํ ์ ์์ (new ์ฌ์ฉ ๋ถ๊ฐ)
โ ์์ ํด๋์ค๋ ๋ฐ๋์ abstract
๋ฉ์๋๋ฅผ ๊ตฌํํด์ผ ํจ
๐น ์์ : ์๋์ฐจ(Car) ์ถ์ ํด๋์ค
// ๐ ์ถ์ ํด๋์ค ์ ์
abstract class Car {
abstract void drive(); // ์ถ์ ๋ฉ์๋ (๊ตฌํ ํ์)
public void stop() { // ์ผ๋ฐ ๋ฉ์๋ (๊ทธ๋๋ก ์ฌ์ฉ ๊ฐ๋ฅ)
System.out.println("์๋์ฐจ๊ฐ ๋ฉ์ถฅ๋๋ค.");
}
}
// ๐๏ธ ์คํฌ์ธ ์นด (์ถ์ ํด๋์ค ์์)
class SportsCar extends Car {
@Override
void drive() {
System.out.println("์คํฌ์ธ ์นด๊ฐ ๋น ๋ฅด๊ฒ ๋ฌ๋ฆฝ๋๋ค!");
}
}
// ๐ ํธ๋ญ (์ถ์ ํด๋์ค ์์)
class Truck extends Car {
@Override
void drive() {
System.out.println("ํธ๋ญ์ด ๋ฌด๊ฒ๊ฒ ์ด๋ํฉ๋๋ค.");
}
}
public class Main {
public static void main(String[] args) {
Car myCar = new SportsCar();
myCar.drive(); // "์คํฌ์ธ ์นด๊ฐ ๋น ๋ฅด๊ฒ ๋ฌ๋ฆฝ๋๋ค!"
myCar.stop(); // "์๋์ฐจ๊ฐ ๋ฉ์ถฅ๋๋ค."
}
}
โ Car
๋ ์ถ์ ํด๋์ค์ด๋ฏ๋ก ์ง์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์ (new Car();
๋ถ๊ฐ)
โ ์์ ํด๋์ค์์ drive()
๋ฅผ ๋ฐ๋์ ๊ตฌํํด์ผ ํจ
โ ๊ณตํต ๋์(stop()
)์ ๊ทธ๋๋ก ์ฌ์ฉ ๊ฐ๋ฅ
2๏ธโฃ ์ธํฐํ์ด์ค(Interface) - โ๋ค์ค ์์์ ์ง์ํ๋ ๊ฐ์ ์ค๊ณโ
์ธํฐํ์ด์ค๋ ํด๋์ค๊ฐ ๋ฐ๋์ ๊ตฌํํด์ผ ํ๋ ๋ฉ์๋๋ฅผ ์ ์ํ๋ ํ์ด๋ค.
์ฆ, ์ธํฐํ์ด์ค๋ ์ค๊ณ๋ ์ญํ ์ ํ๋ฉฐ, ๋ค์ค ๊ตฌํ์ด ๊ฐ๋ฅํ์ฌ ์ ์ฐํ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์ ์๋ค.
๐น ์ธํฐํ์ด์ค์ ํน์ง
โ interface
ํค์๋๋ฅผ ์ฌ์ฉํด ์ ์ธ
โ ๋ชจ๋ ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก public abstract
(๊ตฌํ X, ์ ์ธ๋ง ๊ฐ๋ฅ)
โ ํ๋(๋ณ์)๋ public static final
(์์๋ก๋ง ์ ์ธ ๊ฐ๋ฅ)
โ ๋ค์ค ๊ตฌํ(๋ค์ค ์์)์ด ๊ฐ๋ฅ
๐น ์์ : ๋๋ฌผ(Animal) ์ธํฐํ์ด์ค
// ๐พ ์ธํฐํ์ด์ค ์ ์
interface Animal {
void makeSound(); // ์ถ์ ๋ฉ์๋ (๋ฐ๋์ ๊ตฌํ ํ์)
}
// ๐ถ ๊ฐ์์ง ํด๋์ค (Animal ์ธํฐํ์ด์ค ๊ตฌํ)
class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("๋ฉ๋ฉ!");
}
}
// ๐ฑ ๊ณ ์์ด ํด๋์ค (Animal ์ธํฐํ์ด์ค ๊ตฌํ)
class Cat implements Animal {
@Override
public void makeSound() {
System.out.println("์ผ์น!");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound(); // "๋ฉ๋ฉ!"
myCat.makeSound(); // "์ผ์น!"
}
}
โ ์ธํฐํ์ด์ค Animal
์ Dog
์ Cat
์ด ๊ตฌํ (implements
์ฌ์ฉ)
โ ์ธํฐํ์ด์ค์ ์ ์๋ ๋ฉ์๋๋ ๋ฐ๋์ ๊ตฌํํด์ผ ํจ (makeSound()
)
โ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋คํ์ฑ์ ๊ทน๋ํํ ์ ์์
3๏ธโฃ ์ถ์ ํด๋์ค vs ์ธํฐํ์ด์ค - ์ธ์ ์ฌ์ฉํ ๊น?
ํน์ง | ์ถ์ ํด๋์ค | ์ธํฐํ์ด์ค |
---|---|---|
์์ ๋ฐฉ์ | ๋จ์ผ ์์ (extends ) |
๋ค์ค ๊ตฌํ ๊ฐ๋ฅ (implements ) |
๋ฉ์๋ ๊ตฌํ | ๊ตฌํ๋ ๋ฉ์๋ ํฌํจ ๊ฐ๋ฅ | ๋ชจ๋ ๋ฉ์๋๋ ๊ตฌํ ๋ถ๊ฐ (๊ธฐ๋ณธ์ ์ผ๋ก abstract ) |
๋ณ์ ์ ์ธ | ์ผ๋ฐ ๋ณ์ ์ฌ์ฉ ๊ฐ๋ฅ | public static final (์์)๋ง ์ฌ์ฉ ๊ฐ๋ฅ |
๊ฐ์ฒด ์์ฑ | ์ง์ ์์ฑ ๋ถ๊ฐ | ์ง์ ์์ฑ ๋ถ๊ฐ |
์ฌ์ฉ ๋ชฉ์ | ๊ณตํต ๊ธฐ๋ฅ ์ ๊ณต + ์ผ๋ถ ๊ฐ์ | ์ค๊ณ๋ง ์ ๊ณต, ๋ชจ๋ ๊ตฌํ ๊ฐ์ |
โ ๊ณตํต๋ ๊ธฐ๋ฅ(์ผ๋ถ ๊ตฌํ๋ ๋ฉ์๋ ํฌํจ)๋ ์ ๊ณตํด์ผ ํ๋ค๋ฉด? โ ์ถ์ ํด๋์ค
์ฌ์ฉ
โ ์์ ํ ๋
๋ฆฝ์ ์ธ ์ค๊ณ๋ฅผ ๊ฐ์ ํ๊ณ , ๋ค์ค ๊ตฌํ์ด ํ์ํ๋ค๋ฉด? โ ์ธํฐํ์ด์ค
์ฌ์ฉ
4๏ธโฃ ์ธํฐํ์ด์ค์ ๋ค์ค ๊ตฌํ - Java์ ๋ค์ค ์์ ๋์ฒด
์๋ฐ๋ ๋ค์ค ์์์ ์ง์ํ์ง ์์ง๋ง, ์ธํฐํ์ด์ค๋ฅผ ํตํด ๋ค์ค ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
๐น ์์ : ๋ค์ค ์ธํฐํ์ด์ค ๊ตฌํํ๊ธฐ
// ๐ ๏ธ ์ฒซ ๋ฒ์งธ ์ธํฐํ์ด์ค (์ด์ ๊ฐ๋ฅ)
interface Drivable {
void drive();
}
// ๐ถ ๋ ๋ฒ์งธ ์ธํฐํ์ด์ค (์์
์ฌ์ ๊ฐ๋ฅ)
interface MusicPlayable {
void playMusic();
}
// ๐ ์๋์ฐจ ํด๋์ค (๋ ๊ฐ์ ์ธํฐํ์ด์ค ๊ตฌํ)
class SmartCar implements Drivable, MusicPlayable {
@Override
public void drive() {
System.out.println("์ค๋งํธ์นด๊ฐ ์์จ ์ฃผํํฉ๋๋ค.");
}
@Override
public void playMusic() {
System.out.println("์์
์ ์ฌ์ํฉ๋๋ค.");
}
}
public class Main {
public static void main(String[] args) {
SmartCar myCar = new SmartCar();
myCar.drive(); // "์ค๋งํธ์นด๊ฐ ์์จ ์ฃผํํฉ๋๋ค."
myCar.playMusic(); // "์์
์ ์ฌ์ํฉ๋๋ค."
}
}
โ SmartCar
ํด๋์ค๋ Drivable
๊ณผ MusicPlayable
์ ๋์์ ๊ตฌํ
โ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์ค ์์๊ณผ ์ ์ฌํ ํจ๊ณผ๋ฅผ ๋ผ ์ ์์
๐ฏ 6๋จ๊ณ ์์ฝ
๊ฐ๋ | ์ค๋ช | ์์ |
---|---|---|
์ถ์ ํด๋์ค | ์ผ๋ถ ๋ฉ์๋๋ฅผ ๊ตฌํํ๊ณ , ์ผ๋ถ๋ ๊ฐ์ | abstract class Car { abstract void drive(); } |
์ธํฐํ์ด์ค | ๋ชจ๋ ๋ฉ์๋๋ฅผ ๊ฐ์ ํ๋ฉฐ, ๋ค์ค ๊ตฌํ ๊ฐ๋ฅ | interface Animal { void makeSound(); } |
์ถ์ ํด๋์ค ์ฌ์ฉ ์๊ธฐ | ๊ณตํต ๊ธฐ๋ฅ ์ ๊ณต + ์ผ๋ถ ๊ฐ์ | abstract class Car { void stop() {} } |
์ธํฐํ์ด์ค ์ฌ์ฉ ์๊ธฐ | ๋ค์ค ๊ตฌํ ๊ฐ๋ฅ + ๊ฐ์ ์ฑ ํ์ | class Dog implements Animal {} |
๋ค์ค ๊ตฌํ | ์ฌ๋ฌ ์ธํฐํ์ด์ค๋ฅผ ๋์์ ๊ตฌํ ๊ฐ๋ฅ | class SmartCar implements Drivable, MusicPlayable {} |
โก๏ธ ์ถ์ ํด๋์ค๋ ๊ณตํต ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ฉด์ ์ผ๋ถ ๋ฉ์๋๋ฅผ ๊ฐ์ ํด์ผ ํ ๋, ์ธํฐํ์ด์ค๋ ๋ค์ค ๊ตฌํ์ด ํ์ํ๊ณ ๋ชจ๋ ๊ธฐ๋ฅ์ ๊ฐ์ ํด์ผ ํ ๋ ์ฌ์ฉํ๋ค! ๐
๐ 7๋จ๊ณ: ๊ฐ์ฒด์งํฅ ์ค๊ณ ์์น(SOLID)์ ์์ฉ
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ๋ ค๋ฉด ์ข์ ์ค๊ณ ์์น์ ๋ฐ๋ผ์ผ ํ๋ค.
๋ํ์ ์ธ ๊ฐ์ฒด์งํฅ ์ค๊ณ ์์น์ด ๋ฐ๋ก SOLID ์์น์ด๋ค.
SOLID ์์น์ ๋ฐ๋ฅด๋ฉด ์ ์ง๋ณด์์ฑ, ํ์ฅ์ฑ, ๊ฐ๋ ์ฑ์ด ๋ฐ์ด๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค. ๐
1๏ธโฃ SOLID ์์น์ด๋?
SOLID๋ ๋ค์ฏ ๊ฐ์ง ๊ฐ์ฒด์งํฅ ์ค๊ณ ์์น์ ์ ๊ธ์๋ฅผ ๋ด ๊ฒ์ด๋ค.
์ด ์์น๋ค์ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ฝ๊ฒ ํ๊ณ , ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๋ ๋ฐ ๋์์ ์ค๋ค.
์์น | ์ค๋ช |
---|---|
S - ๋จ์ผ ์ฑ ์ ์์น (Single Responsibility Principle) | ํ๋์ ํด๋์ค๋ ํ๋์ ์ฑ ์๋ง ๊ฐ์ ธ์ผ ํ๋ค. |
O - ๊ฐ๋ฐฉ-ํ์ ์์น (Open-Closed Principle) | ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ํ์ฅํ ์ ์์ด์ผ ํ๋ค. |
L - ๋ฆฌ์ค์ฝํ ์นํ ์์น (Liskov Substitution Principle) | ์์ ํด๋์ค๋ ๋ถ๋ชจ ํด๋์ค๋ฅผ ๋์ฒดํ ์ ์์ด์ผ ํ๋ค. |
I - ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น (Interface Segregation Principle) | ํ๋์ ๊ฑฐ๋ํ ์ธํฐํ์ด์ค๋ณด๋ค๋ ์ฌ๋ฌ ๊ฐ์ ์์ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค. |
D - ์์กด ์ญ์ ์์น (Dependency Inversion Principle) | ์์(์ถ์) ๋ชจ๋์ด ํ์(๊ตฌ์ฒด) ๋ชจ๋์ ์์กดํ๋ฉด ์ ๋๋ค. |
2๏ธโฃ SOLID ์์น์ ์ฝ๋๋ก ์ดํดํ๊ธฐ
๐น (S) ๋จ์ผ ์ฑ ์ ์์น (Single Responsibility Principle, SRP)
โ ํ ํด๋์ค๋ ํ๋์ ์ฑ ์๋ง ๊ฐ์ ธ์ผ ํ๋ค.
โ ํ๋์ ์ด์ ๋ก๋ง ๋ณ๊ฒฝ๋์ด์ผ ํ๋ค.
โ ์๋ฐ ์์ (ํ๋์ ํด๋์ค๊ฐ ๋๋ฌด ๋ง์ ์ผ์ ํจ)
class OrderManager {
void processOrder() {
System.out.println("์ฃผ๋ฌธ์ ์ฒ๋ฆฌํฉ๋๋ค.");
}
void printInvoice() {
System.out.println("์์์ฆ์ ์ถ๋ ฅํฉ๋๋ค.");
}
void sendEmailNotification() {
System.out.println("์ด๋ฉ์ผ์ ๋ฐ์กํฉ๋๋ค.");
}
}
โ OrderManager
ํด๋์ค๊ฐ ์ฃผ๋ฌธ ์ฒ๋ฆฌ, ์์์ฆ ์ถ๋ ฅ, ์ด๋ฉ์ผ ์ ์ก๊น์ง ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ด๋น
โ ์ฑ ์์ด ๋ง์์ง๋ฉด ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ง
โ ์ฌ๋ฐ๋ฅธ ์์ (์ฑ ์์ ๋ถ๋ฆฌ)
class OrderProcessor {
void processOrder() {
System.out.println("์ฃผ๋ฌธ์ ์ฒ๋ฆฌํฉ๋๋ค.");
}
}
class InvoicePrinter {
void printInvoice() {
System.out.println("์์์ฆ์ ์ถ๋ ฅํฉ๋๋ค.");
}
}
class EmailNotifier {
void sendEmailNotification() {
System.out.println("์ด๋ฉ์ผ์ ๋ฐ์กํฉ๋๋ค.");
}
}
โ OrderProcessor
, InvoicePrinter
, EmailNotifier
ํด๋์ค๋ฅผ ๊ฐ๊ฐ ๋ง๋ค์ด ์ฑ
์์ ๋ถ๋ฆฌ
โ ์ ์ง๋ณด์์ ํ์ฅ์ฑ์ด ํฅ์๋จ
๐น (O) ๊ฐ๋ฐฉ-ํ์ ์์น (Open-Closed Principle, OCP)
โ ์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ ๊ธฐ๋ฅ์ ํ์ฅํ ์ ์์ด์ผ ํ๋ค.
โ ์๋ก์ด ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋ ๋ ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ํ์ฅํ ์ ์๋๋ก ์ค๊ณํด์ผ ํ๋ค.
โ ์๋ฐ ์์ (๊ธฐ์กด ์ฝ๋๋ฅผ ์์ ํด์ผ ํ๋ ๊ฒฝ์ฐ)
class PaymentProcessor {
void processPayment(String paymentType) {
if (paymentType.equals("CreditCard")) {
System.out.println("์ ์ฉ์นด๋ ๊ฒฐ์ ์ฒ๋ฆฌ");
} else if (paymentType.equals("PayPal")) {
System.out.println("PayPal ๊ฒฐ์ ์ฒ๋ฆฌ");
}
}
}
โ processPayment()
์ ์๋ก์ด ๊ฒฐ์ ์๋จ์ ์ถ๊ฐํ ๋๋ง๋ค ์ฝ๋๋ฅผ ์์ ํด์ผ ํจ
โ ์ฌ๋ฐ๋ฅธ ์์ (์๋ก์ด ๊ฒฐ์ ๋ฐฉ์ ์ถ๊ฐ ๊ฐ๋ฅ)
interface PaymentMethod {
void processPayment();
}
class CreditCardPayment implements PaymentMethod {
public void processPayment() {
System.out.println("์ ์ฉ์นด๋ ๊ฒฐ์ ์ฒ๋ฆฌ");
}
}
class PayPalPayment implements PaymentMethod {
public void processPayment() {
System.out.println("PayPal ๊ฒฐ์ ์ฒ๋ฆฌ");
}
}
class PaymentProcessor {
void processPayment(PaymentMethod paymentMethod) {
paymentMethod.processPayment();
}
}
โ ์๋ก์ด ๊ฒฐ์ ๋ฐฉ์์ ์ถ๊ฐํ ๋ PaymentProcessor
์ฝ๋๋ฅผ ์์ ํ ํ์ ์์
โ ํ์ฅ์๋ ์ด๋ ค ์๊ณ (Open), ์์ ์๋ ๋ซํ ์์(Closed)
๐น (L) ๋ฆฌ์ค์ฝํ ์นํ ์์น (Liskov Substitution Principle, LSP)
โ ์์ ํด๋์ค๋ ๋ถ๋ชจ ํด๋์ค๋ฅผ ๋์ฒดํ ์ ์์ด์ผ ํ๋ค.
โ ์์์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉ๋์๋์ง ๊ฒ์ฆํ๋ ์์น์ด๋ค.
โ ์๋ฐ ์์ (๋ถ๋ชจ ํด๋์ค ๊ธฐ๋ฅ์ ์ ํํ๋ ์์ ํด๋์ค)
class Bird {
void fly() {
System.out.println("์๊ฐ ๋ ์๊ฐ๋๋ค.");
}
}
class Penguin extends Bird {
@Override
void fly() {
throw new UnsupportedOperationException("ํญ๊ท์ ๋ ์ ์์ต๋๋ค.");
}
}
โ Penguin
ํด๋์ค๊ฐ Bird
ํด๋์ค๋ฅผ ์์ํ์ง๋ง, fly()
๋ฅผ ์ฌ์ฉํ ์ ์์ โ ์๋ชป๋ ์ค๊ณ
โ ์ฌ๋ฐ๋ฅธ ์์ (๋ถ๋ชจ ํด๋์ค๋ฅผ ๋์ฒดํ ์ ์๋๋ก ์์ )
abstract class Bird {
abstract void move();
}
class Sparrow extends Bird {
@Override
void move() {
System.out.println("์ฐธ์๊ฐ ๋ ์๊ฐ๋๋ค.");
}
}
class Penguin extends Bird {
@Override
void move() {
System.out.println("ํญ๊ท์ด ํค์์นฉ๋๋ค.");
}
}
โ move()
๋ผ๋ ์ผ๋ฐ์ ์ธ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ Penguin
๊ณผ Sparrow
๋ฅผ ๋์ผํ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌ ๊ฐ๋ฅ
๐น (I) ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น (Interface Segregation Principle, ISP)
โ ํ๋์ ํฐ ์ธํฐํ์ด์ค๋ณด๋ค๋ ์ฌ๋ฌ ๊ฐ์ ์์ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค์ด ํ์ํ ๊ธฐ๋ฅ๋ง ๊ตฌํํ ์ ์๋๋ก ํด์ผ ํ๋ค.
โ ์๋ฐ ์์ (๋ถํ์ํ ๋ฉ์๋ ๊ตฌํ ๊ฐ์)
interface Worker {
void work();
void eat();
}
class Robot implements Worker {
@Override
public void work() {
System.out.println("๋ก๋ด์ด ์ผ์ ํฉ๋๋ค.");
}
@Override
public void eat() {
throw new UnsupportedOperationException("๋ก๋ด์ ๋ฐฅ์ ๋จน์ง ์์ต๋๋ค.");
}
}
โ Robot
ํด๋์ค๋ eat()
์ ๊ตฌํํ ํ์๊ฐ ์์
โ ์ฌ๋ฐ๋ฅธ ์์ (์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์ ์ฉ)
interface Workable {
void work();
}
interface Eatable {
void eat();
}
class Human implements Workable, Eatable {
public void work() {
System.out.println("์ฌ๋์ด ์ผ์ ํฉ๋๋ค.");
}
public void eat() {
System.out.println("์ฌ๋์ด ๋ฐฅ์ ๋จน์ต๋๋ค.");
}
}
class Robot implements Workable {
public void work() {
System.out.println("๋ก๋ด์ด ์ผ์ ํฉ๋๋ค.");
}
}
โ ์ธํฐํ์ด์ค๋ฅผ ๋ถ๋ฆฌํ์ฌ, ํ์ํ ๊ธฐ๋ฅ๋ง ๊ตฌํํ๋๋ก ํจ
๐น (D) ์์กด ์ญ์ ์์น (Dependency Inversion Principle, DIP)
โ ๊ตฌ์ฒด์ ์ธ ํด๋์ค๊ฐ ์๋, ์ถ์์ ์ธ ์ธํฐํ์ด์ค์ ์์กดํด์ผ ํ๋ค.
โ โ์์(์ถ์) ๋ชจ๋์ด ํ์(๊ตฌ์ฒด) ๋ชจ๋์ ์์กดํ๋ฉด ์ ๋๋ค.โ
interface MessageSender {
void sendMessage(String message);
}
class EmailSender implements MessageSender {
public void sendMessage(String message) {
System.out.println("์ด๋ฉ์ผ ์ ์ก: " + message);
}
}
class NotificationService {
private MessageSender sender;
NotificationService(MessageSender sender) {
this.sender = sender;
}
void notifyUser(String message) {
sender.sendMessage(message);
}
}
โ NotificationService
๋ EmailSender
๊ฐ ์๋๋ผ MessageSender
์ธํฐํ์ด์ค์ ์์กด
โ ๋ค๋ฅธ ๋ฉ์์ง ์ ์ก ๋ฐฉ์(SMS, ์นด์นด์คํก ๋ฑ) ์ถ๊ฐ ๊ฐ๋ฅ
๐ฏ 7๋จ๊ณ ์์ฝ: SOLID ์์น ์ ์ฉํ๋ฉด ์ข์ ์
โ ์ ์ง๋ณด์์ฑ์ด ๋ฐ์ด๋ ์ฝ๋
โ ํ์ฅํ๊ธฐ ์ฌ์ด ๊ตฌ์กฐ
โ ๋ฒ๊ทธ ๋ฐ์ ํ๋ฅ ๊ฐ์
โก๏ธ SOLID ์์น์ ๋ฐ๋ฅด๋ฉด ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ด ๋์ฑ ๊ฐ๋ ฅํด์ง๋ค! ๐