객체지ν–₯ ν”„λ‘œκ·Έλž˜λ° (OOP)

μΆœμ œλΉˆλ„: 상
λΉˆμΆœνƒœκ·Έ: 클래슀, μΈμŠ€ν„΄μŠ€, 상속, 좔상 클래슀, μΈν„°νŽ˜μ΄μŠ€

클래슀 섀계

κΈ°λ³Έ νŠΉμ§•

  • main λ©”μ†Œλ“œλ₯Ό ν¬ν•¨ν•˜λŠ” ν΄λž˜μŠ€κ°€ κ°€μž₯ λ¨Όμ € 싀행됨
  • 클래슀의 κ΅¬μ„±μš”μ†Œμ—λŠ” 멀버 λ³€μˆ˜, 멀버 λ©”μ†Œλ“œκ°€ 있음
  • μ™ΈλΆ€ 접근이 λΆˆκ°€λŠ₯ν•˜λ„λ‘ μ œν•œ(μΊ‘μŠν™”) 해야함

κΈ°λ³Έ 좜λ ₯ λ©”μ†Œλ“œ

  • 좜λ ₯: System.out.print()
  • 좜λ ₯+μ€„λ°”κΏˆ: System.out.println()
  • μ„œμ‹μ— μ˜ν•œ 좜λ ₯: System.out.printf()

μ ‘κ·Ό μ œν•œμž

클래슀 λ‚΄ λ©€λ²„λ“€μ˜ μ ‘κ·Ό μˆ˜μ€€μ„ κ²°μ •ν•˜λŠ” ν† ν°μœΌλ‘œ, ν”„λ‘œκ·Έλž¨, νŒ¨ν‚€μ§€, ν•˜μœ„ 클래슀, μžμ‹ μ˜ 클래슀 순으둜 μ ‘κ·Όμˆ˜μ€€μ„ 결정함

μ œν•œμž μ„€λͺ…
public λͺ¨λ“  κ°μ²΄μ—μ„œ μ ‘κ·Ό κ°€λŠ₯
default 같은 νŒ¨ν‚€μ§€ λ‚΄μ—μ„œ μ ‘κ·Ό κ°€λŠ₯
protected μžμ‹ κ³Ό ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯
private μžμ‹ μ˜ ν΄λž˜μŠ€μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯

μΈμŠ€ν„΄μŠ€

μΈμŠ€ν„΄μŠ€ 생성 및 μ ‘κ·Ό

// μΈμŠ€ν„΄μŠ€ 생성
<클래슀λͺ…> <λ³€μˆ˜λͺ…> = new <클래슀λͺ…>();

// μΈμŠ€ν„΄μŠ€ 멀버 μ ‘κ·Ό
<κ°μ²΄λ³€μˆ˜>.<멀버이름>

λ³€μˆ˜ μ’…λ₯˜ μ˜ˆμ‹œ

public class Variable {
    int c;                      // μΈμŠ€ν„΄μŠ€λ³€μˆ˜(λ©€λ²„λ³€μˆ˜)
    static String d;            // 클래슀 λ³€μˆ˜(λ©€λ²„λ³€μˆ˜)
    
    void func(int c){          // λ§€κ°œλ³€μˆ˜(μ§€μ—­λ³€μˆ˜)
        this.c = c;            // λ©€λ²„λ³€μˆ˜ c에 μ§€μ—­λ³€μˆ˜ cκ°’ ν• λ‹Ή
    }
    
    public static void main(String args[]) {
        int a = 30;            // μ •μˆ˜ν˜•λ³€μˆ˜(μ§€μ—­λ³€μˆ˜)
        Variable b = new Variable(); // μ°Έμ‘°ν˜•λ³€μˆ˜(μ§€μ—­λ³€μˆ˜)
        b.func(a);
    }
}

클래슀 λ³€μˆ˜

  • νŠΉλ³„ν•œ κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ 접근을 μ œν•œν•΄λ‘ 
  • κ³΅μœ ν•˜λŠ” 데이터가 ν•„μš”ν•  λ•Œ μ‚¬μš©
  • μ„ μ–Έ ν˜•μ‹: [<μ ‘κ·Όμ œν•œμž>] static <μžλ£Œν˜•> <λ³€μˆ˜λͺ…>;
  • ν΄λž˜μŠ€κ°€ μ½”λ“œμ— μ–ΈκΈ‰λ˜λŠ” μˆœκ°„ μƒμ„±λ˜λ©°, ν”„λ‘œκ·Έλž¨μ΄ 끝날 λ•ŒκΉŒμ§€ μœ μ§€
  • 클래슀 λ‚΄λΆ€μ—μ„œ this둜 뢈러옴

μƒμ„±μž λ©”μ†Œλ“œ

  • 클래슀λͺ…κ³Ό 같은 μ΄λ¦„μœΌλ‘œ 쑴재
  • μžλ™μœΌλ‘œ μ‹€ν–‰λ˜λ©° 별도 μ‹€ν–‰ λΆˆκ°€
  • 리턴문 μ‚¬μš© λΆˆκ°€λŠ₯
  • μ΄ˆκΈ°ν™” μž‘μ—…μ— μ‚¬μš©
  • μ˜€λ²„λ‘œλ”©: λ™μΌν•œ λ©”μ†Œλ“œλͺ…을 κ°€μ§„ λ©”μ†Œλ“œλ“€μ„ κ°œμˆ˜μ™€ μœ ν˜•μ„ κΈ°μ€€μœΌλ‘œ ꡬ뢄

객체지ν–₯ 기술 적용

상속

  • extends ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄μ„œ μƒμœ„ν΄λž˜μŠ€ μ§€μ •
  • ν˜•μ‹: class <ν•˜μœ„ 클래슀λͺ…> extends <μƒμœ„ 클래슀λͺ…> { ... }
  • μž¬μ‚¬μš©, μž¬μ •μ˜, μΆ”κ°€ 멀버λ₯Ό ν™•μž₯ν•΄μ„œ κ΅¬ν˜„
  • λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©: μƒμœ„ 클래슀의 λ©”μ†Œλ“œλ₯Ό μž¬μ •μ˜ν•˜μ—¬ μ‚¬μš©ν•˜λŠ” 기술

μ—…μΊμŠ€νŒ… μ˜ˆμ‹œ

class SuperObject {
    public void paint() {
        draw();
    }
    public void draw() {        // 4. μ˜€λ²„λΌμ΄λ”©λœ ν•˜μœ„ 클래슀의 paint 호좜
        draw();                 // 3. μžκΈ°μžμ‹  λ‹€μ‹œ ν˜ΈμΆœν•¨
        System.out.println("Super Object"); // 6. λ§ˆμ§€λ§‰μ— 좜λ ₯
    }
}

class SubObject extends SuperObject {
    public void paint() {
        super.draw();          // 2. μ‹€μ œ ν˜ΈμΆœλ˜λŠ” λ©”μ†Œλ“œ -> μƒμœ„ 클래슀의 draw λ©”μ†Œλ“œ 호좜
    }
    public void draw() {
        System.out.println("Sub Object"); // 5. λ¬Έμžμ—΄ 좜λ ₯
    }
}

public class Main {
    public static void main(String[] args) {
        SuperObject b = new SubObject(); // 1. μƒμœ„ μ°Έμ‘°λ³€μˆ˜λ‘œ μ—…μΊμŠ€νŒ…
        b.paint();
    }
}

// κ²°κ³Ό
// Sub Object
// Super Object

좔상 클래슀

abstract class Shape {          // 좔상 클래슀 μ •μ˜
    abstract void draw();       // 좔상 λ©”μ†Œλ“œ μ •μ˜
}

class Circle extends Shape {
    void draw() {              // 좔상 λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©
        System.out.println("원을 κ·Έλ¦½λ‹ˆλ‹€");
    }
}

class Rectangle extends Shape {
    void draw() {              // 좔상 λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©
        System.out.println("μ‚¬κ°ν˜•μ„ κ·Έλ¦½λ‹ˆλ‹€");
    }
}

public class Helloworld {
    public static void main(String[] args) {
        Circle c1 = new Circle();
        Rectangle r1 = new Rectangle();
        c1.draw();             // λ©”μ†Œλ“œλͺ… 톡일 κ°€λŠ₯
        r1.draw();
    }
}

// κ²°κ³Ό
// 원을 κ·Έλ¦½λ‹ˆλ‹€
// μ‚¬κ°ν˜•μ„ κ·Έλ¦½λ‹ˆλ‹€

μΈν„°νŽ˜μ΄μŠ€

닀쀑 μƒμ†μ˜ λ¬Έμ œμ μ„ ν•΄κ²°ν•˜κΈ° μœ„ν•œ λ°©λ²•μœΌλ‘œ, μžλ°”λŠ” λ‘˜ μ΄μƒμ˜ μƒμœ„ 클래슀λ₯Ό μƒμ†λ°›λŠ” 닀쀑상속을 κΈˆμ§€ν•¨. 닀쀑상속을 λ°©μ§€ν•˜λ©΄μ„œ λ‹€μ€‘μƒμ†μ˜ 이점을 κ°€μ§€λŠ” κΈ°λŠ₯이 μΈν„°νŽ˜μ΄μŠ€μž„

νŠΉμ§•

  • λͺ¨λ“  λ©”μ†Œλ“œκ°€ 좔상 λ©”μ†Œλ“œλ‘œλ§Œ ꡬ성
  • interface와 implements ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄μ„œ κ΅¬ν˜„, 상속
  • 상속은 κΈ°μ‘΄ 클래슀의 멀버λ₯Ό β€˜ν™•μž₯β€™ν•˜λŠ” κ°œλ…μ΄μ§€λ§Œ μΈν„°νŽ˜μ΄μŠ€λŠ” ν™•μž₯된 클래슀의 κΈ°λŠ₯을 β€˜μ œν•œβ€™ν•˜κ±°λ‚˜ β€˜λ³€κ²½β€™ν•˜λŠ” β€˜λ‹€ν˜•μ„±β€™μ˜ κ°œλ…
interface Coffee {             // μƒμœ„
    abstract void drink_coffee();
}

interface Cookie {             // μƒμœ„
    abstract void eat_cookie();
}

class Cafe implements Coffee, Cookie { // ν•˜μœ„
    public void drink_coffee() {
        System.out.println("컀피λ₯Ό λ§ˆμ‹ λ‹€.");
    }
    public void eat_cookie() {
        System.out.println("μΏ ν‚€λ₯Ό λ¨ΉλŠ”λ‹€.");
    }
    public void talk() {
        System.out.println("λŒ€ν™”λ₯Ό ν•œλ‹€.");
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        Cafe k = new Cafe();
        k.drink_coffee();
        k.eat_cookie();
        k.talk();
        
        Coffee c = k;          // μ—…μΊμŠ€νŒ…
        c.drink_coffee();      // μ»€ν”Όλ§Œ λ§ˆμ‹€ 수 있음
        
        Cookie x = k;          // μ—…μΊμŠ€νŒ…
        x.eat_cookie();        // μΏ ν‚€λ§Œ 먹을 수 있음
    }
}

μ˜ˆμ™Έμ²˜λ¦¬

  • μ‹€ν–‰ 도쀑에 λ¬Έμ œκ°€ λ°œμƒν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ΄ λ©ˆμΆ”κ±°λ‚˜ μ’…λ£Œλ˜λŠ” 것을 λ°©μ§€ν•˜κΈ° μœ„ν•œ μ½”λ“œ
  • μ˜€νƒ€λŠ” 문법 였λ₯˜(Syntax Error), μ˜λ„μΉ˜ μ•Šμ€ μž‘λ™ 및 μž…λ ₯을 μ˜ˆμ™ΈλΌκ³  함
  • μ˜ˆμ™Έλ₯Ό 식별할 μ˜μ—­μ„ λ³„λ„λ‘œ μ§€μ •ν•΄μ•Ό 함
public class HelloWorld {
    public static void main(String[] args) {
        try {                  // μ˜ˆμ™Έ 감지 μ˜μ—­
            <μ½”λ“œ μ˜μ—­>
        }
        catch() {              // μ˜ˆμ™Έ 감지 μ‹œ μ‹€ν–‰ μ˜μ—­
            <μ½”λ“œ μ˜μ—­>
        }
        finally {              // 무쑰건 μ‹€ν–‰λ˜λŠ” μ˜μ—­
            <μ½”λ“œ μ˜μ—­>
        }
    }
}

μŠ€λ ˆλ“œ(Thread)

ν•˜λ‚˜μ˜ ν”„λ‘œμ„ΈμŠ€(ν”„λ‘œκ·Έλž¨)μ—μ„œ λ‘˜ μ΄μƒμ˜ 일을 λ™μ‹œμ— μˆ˜ν–‰ν•˜λŠ” 것

Thread 클래슀 상속을 ν†΅ν•œ κ΅¬ν˜„

class Box extends Thread {     // Thread 클래슀 상속
    public void run() {        // run λ©”μ†Œλ“œ μž¬μ •μ˜
        System.out.println("message"); // μŠ€λ ˆλ“œ μ‹€ν–‰ μ‹œ μˆ˜ν–‰λ˜λŠ” μ˜μ—­
    }
}

public class Main {
    public static void main(String[] args) {
        Box a = new Box();     // 일반적인 객체 생성 방식
        a.start();             // μŠ€λ ˆλ“œ μˆ˜ν–‰ λ©”μ†Œλ“œ
    }
}

// κ²°κ³Ό
// message

Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν†΅ν•œ κ΅¬ν˜„

class Box implements Runnable { // implements μΈν„°νŽ˜μ΄μŠ€ 상속
    public void run() {         // run λ©”μ†Œλ“œ μž¬μ •μ˜
        System.out.println("message"); // μŠ€λ ˆλ“œ μ‹€ν–‰ μ‹œ μˆ˜ν–‰λ˜λŠ”μ˜μ—­
    }
}

public class Main {
    public static void main(String[] args) {
        Thread t = new Thread(new Box()); // Thread μƒμ„±μžμ—μ„œ λ‹€λ₯Έ μƒμ„±μž 호좜
        t.start();              // μŠ€λ ˆλ“œ μˆ˜ν–‰ λ©”μ†Œλ“œ
    }
}

// κ²°κ³Ό
// message

λ©€ν‹°μŠ€λ ˆλ”©

  • λ‹€μˆ˜μ˜ μŠ€λ ˆλ“œλ₯Ό λ™μ‹œμ— μ‹€ν–‰
  • μžμ› μ†ŒλΉ„λ₯Ό 쀄일 수 있음
  • μžμ›μ„ κ³΅μœ ν•˜λ―€λ‘œ 좩돌이 일어날 κ°€λŠ₯μ„±κ³Ό λ³΅μž‘ν•œ μ½”λ”©μœΌλ‘œ 버그 κ°€λŠ₯성이 컀짐

μŠ€λ ˆλ“œ μƒνƒœ

  1. Runnable: start λ©”μ†Œλ“œλ‘œ 싀행이 μ€€λΉ„λœ μƒνƒœ
  2. Running: run λ©”μ†Œλ“œλ‘œ μŠ€λ ˆλ“œκ°€ μ‹€ν–‰λ˜λŠ” μƒνƒœ
  3. Blocked: μŠ€λ ˆλ“œκ°€ μž μ‹œ μž‘μ—…μ„ 멈좘 단계
  4. Dead(Done): μŠ€λ ˆλ“œ μˆ˜ν–‰μ΄ μ™„λ£Œλœ μƒνƒœ