# 상속(inheritance)

written by sohyeon, hyemin πŸ’‘


# 1.μƒμ†μ˜ μ •μ˜μ™€ μž₯점

μƒμ†μ΄λž€, 기쑴의 클래슀λ₯Ό μž¬μ‚¬μš©ν•˜μ—¬ μƒˆλ‘œμš΄ 클래슀λ₯Ό μž‘μ„±ν•˜λŠ” 것이닀.
상속을 ν†΅ν•΄μ„œ 클래슀λ₯Ό μž‘μ„±ν•˜λ©΄ 보닀 적은 μ–‘μ˜ μ½”λ“œλ‘œ μƒˆλ‘œμš΄ 클래슀λ₯Ό μž‘μ„±ν•  수 있고 μ½”λ“œλ₯Ό κ³΅ν†΅μ μœΌλ‘œ 관리할 수 있기 λ•Œλ¬Έμ— μ½”λ“œμ˜ μΆ”κ°€ 및 변경이 맀우 μš©μ΄ν•˜λ‹€.

  • 쑰상 클래슀 : μƒμ†ν•΄μ£ΌλŠ” 클래슀 ( λΆ€λͺ¨(parent)클래슀, μƒμœ„(super)클래슀, 기반(base)클래슀 )
  • μžμ† 클래슀 : 상속 λ°›λŠ” 클래슀 ( μžμ‹(child)클래슀, ν•˜μœ„(sub)클래슀, νŒŒμƒλœ(derived)클래슀 )
* μƒμ„±μžμ™€ μ΄ˆκΈ°ν™” λΈ”λŸ­μ€ μƒμ†λ˜μ§€ μ•ŠλŠ”λ‹€. λ©€λ²„λ§Œ μƒμ†λœλ‹€.
* μžμ† 클래슀의 멀버 κ°œμˆ˜λŠ” 쑰상 ν΄λž˜μŠ€λ³΄λ‹€ 항상 κ°™κ±°λ‚˜ λ§Žλ‹€.
* 클래슀 Child와 Child2κ°€ λͺ¨λ‘ Parent클래슀λ₯Ό 상속받고 μžˆλ‹€.
* Parent클래슀의 μžμ†μΈ Childν΄λž˜μŠ€μ™€ Child2ν΄λž˜μŠ€λŠ” μ‘°μƒμ˜ 멀버λ₯Ό 상속받기 λ•Œλ¬Έμ—, Parentν΄λž˜μŠ€μ— μƒˆλ‘œμš΄ 멀버λ₯Ό μΆ”κ°€ν•΄μ£ΌλŠ” 것은 Childν΄λž˜μŠ€μ™€ Child2ν΄λž˜μŠ€μ— μƒˆλ‘œμš΄ 멀버λ₯Ό μΆ”κ°€ν•΄μ£ΌλŠ” 것과 같은 νš¨κ³Όλ‹€.
* μžμ† 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λ©΄ 쑰상 클래슀의 멀버도 ν•¨κ»˜ μƒμ„±λ˜κΈ° λ•Œλ¬Έμ— λ”°λ‘œ 쑰상 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³ λ„ 쑰상 클래슀의 멀버듀을 μ‚¬μš©ν•  수 μžˆλ‹€.

# 2. ν΄λž˜μŠ€κ°„μ˜ 관계 - 포함관계

상속이외에도 클래슀λ₯Ό μž¬μ‚¬μš©ν•˜λŠ” λ°©λ²•μœΌλ‘œλŠ” 클래슀 간에 포함(Composite)관계λ₯Ό λ§Ίμ–΄μ£ΌλŠ” 것이닀.
클래슀 κ°„μ˜ 포함관계λ₯Ό λ§Ίμ–΄ μ£ΌλŠ” 것은 ν•œ 클래슀의 λ©€λ²„λ³€μˆ˜λ‘œ λ‹€λ₯Έ 클래슀 νƒ€μž…μ˜ μ°Έμ‘°λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 것을 λœ»ν•œλ‹€.

class Circle {
    int x;  // μ›μ μ˜ xμ’Œν‘œ
    int y;  // μ›μ μ˜ yμ’Œν‘œ
    int r;  // λ°˜μ§€λ¦„(radius)
}

class Point {
    int x;  // μ›μ μ˜ xμ’Œν‘œ
    int y;  // μ›μ μ˜ yμ’Œν‘œ
}

Point클래슀λ₯Ό μž¬μ‚¬μš©ν•΄μ„œ Circle클래슀λ₯Ό μž‘μ„±ν•œλ‹€.

class Circle {
    Point c = new Point(); // 원점
    int r;
}

λ‹¨μœ„λ³„λ‘œ μ—¬λŸ¬ 개의 클래슀λ₯Ό μž‘μ„±ν•œ λ‹€μŒ, 이 λ‹¨μœ„ ν΄λž˜μŠ€λ“€μ„ 포함관계(λ©€λ²„λ³€μˆ˜)둜 μž¬μ‚¬μš©ν•˜λ©΄ 보닀 κ°„κ²°ν•˜κ³  μ†μ‰½κ²Œ 클래슀λ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.


# 3. ν΄λž˜μŠ€κ°„μ˜ 관계 κ²°μ •ν•˜κΈ°

클래슀λ₯Ό μž‘μ„±ν•˜λŠ”λ° μžˆμ–΄μ„œ 상속관계λ₯Ό λ§Ίμ–΄ 쀄 것인지 포함관계λ₯Ό λ§Ίμ–΄ 쀄 것인지 κ²°μ •ν•˜λŠ” 것은 λ•Œλ•Œλ‘œ 혼돈슀러울 수 μžˆλ‹€.

상속관계 : '~은 ~이닀.(is-a)'
포함관계 : '~은 ~을 가지고 μžˆλ‹€.(has-a)'
  • Carν΄λž˜μŠ€μ™€ SportsCarν΄λž˜μŠ€λŠ” SportsCarλŠ” Car이닀. (상속관계)
  • Cardν΄λž˜μŠ€μ™€ Deckν΄λž˜μŠ€λŠ” Deck은 Cardλ₯Ό 가지고 μžˆλ‹€. (포함관계)

# ex) 포함관계 예제

class DeckTest {
    public static void main(String args[]) {
        Deck d = new Deck();     // μΉ΄λ“œ ν•œ λ²Œμ„ λ§Œλ“ λ‹€.
        Card c = d.pick(0);      // μ„žκΈ° 전에 제일 μœ„μ˜ μΉ΄λ“œλ₯Ό λ½‘λŠ”λ‹€. cardArr[0]에 μ €μž₯된 Card객체의 μ£Όμ†Œκ°€ μ°Έμ‘°λ³€μˆ˜ c에 μ €μž₯
        System.out.println(c);   // System.out.println(c.toString());κ³Ό κ°™λ‹€.
        
        d.shuffle();             // μΉ΄λ“œλ₯Ό μ„žλŠ”λ‹€.
        c = d.pick(0);           // μ„žμ€ 후에 제일 μœ„μ˜ μΉ΄λ“œλ₯Ό λ½‘λŠ”λ‹€.
        System.out.println(c); 
    }
}

class Deck {
    final int CARD_NUM = 52;     // μΉ΄λ“œμ˜ 개수
    Card cardArr[] = new Card[CARD_NUM];  // Card객체 배열을 포함
    
    Deck() {  // Deck의 μΉ΄λ“œλ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€.
        int i = 0;
        
        for(int k=Card.KIND_MAX; k>0; k--)      
            for(int n=0; n<Card.NUM_MAX; n++)
                cardArr[i++] = new Card(k, n+1);   
    }
    
    Card pick(int index) {       // μ§€μ •λœ μœ„μΉ˜μ— μžˆλŠ” μΉ΄λ“œ ν•˜λ‚˜λ₯Ό κΊΌλ‚΄μ„œ λ°˜ν™˜
        return cardArr[index];
    }
    
    Card pick() {                // Deckμ—μ„œ μΉ΄λ“œ ν•˜λ‚˜λ₯Ό μ„ νƒν•œλ‹€.
        int index = (int)(Math.random() * CARD_NUM);
        return pick(intdex);
    }
    
    void shuffle() {             // μΉ΄λ“œμ˜ μˆœμ„œλ₯Ό μ„žλŠ”λ‹€.
        for(int i=0; i < cardArr.length; i++) {
            int r = (int)(Math.random() * CARD_NUM);
    
            Card temp = cardArr[i];
            cardArr[i] = cardArr[r];
            cardArr[r] = temp;
        }
    }
}

class Card {
    static final int KIND_MAX = 4;  // μΉ΄λ“œ 무늬의 수
    static final int NUM_MAX = 13;  // λ¬΄λŠ¬λ³„ μΉ΄λ“œ 수

    static final int SPACE = 4;
    static final int DIAMOND = 3;
    static final int HEART = 2;
    static final int CLOVER = 1;
    int kind;
    int number;
    
    Card() {
        this(SPACE, 1);
    }
    
    Card(int kind, int number) {
        this.kind = kind;
        this.number = number;
    }
    
    public String toString() {  // toString()은 μΈμŠ€ν„΄μŠ€μ˜ 정보λ₯Ό λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•  λͺ©μ μœΌλ‘œ μ •μ˜λœ 것
        String[] kinds = {"", "CLOVER", "HEART", "DIAMOND", "SPACE"};
        String numbers = "0123456789XJQK";
        
        return "kind : " + kinds[this.kind] + ", number : " + numbers.charAt(this.number);
    }
}
  • toString( )은 λͺ¨λ“  클래슀의 쑰상인 Objectν΄λž˜μŠ€μ— μ •μ˜λœ κ²ƒμœΌλ‘œ, μ–΄λ–€ μ’…λ₯˜μ˜ 객체에 λŒ€ν•΄μ„œλ„ toString( ) ν˜ΈμΆœν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€.

# 4. 단일 상속(single inheritance)

  • μžλ°”μ—μ„œλŠ” λ‹¨μΌμƒμ†λ§Œμ„ ν—ˆμš©ν•œλ‹€. 닀쀑상속을 ν—ˆμš©ν•˜λ©΄ μ—¬λŸ¬ ν΄λž˜μŠ€λ‘œλΆ€ν„° 상속받을 수 있기 λ•Œλ¬Έμ— 볡합적인 κΈ°λŠ₯을 가진 클래슀λ₯Ό μ‰½κ²Œ μž‘μ„±ν•  수 μžˆλ‹€λŠ” μž₯점이 μžˆμ§€λ§Œ, μ„œλ‘œ λ‹€λ₯Έ ν΄λž˜μŠ€λ‘œλΆ€ν„° 상속받은 λ©€λ²„κ°„μ˜ 이름이 같은 경우 ꡬ별할 수 μžˆλŠ” 방법이 μ—†λ‹€λŠ” 단점을 가지고 μžˆλ‹€.

# 5. Object 클래슀 - λͺ¨λ“  클래슀의 쑰상

Objectν΄λž˜μŠ€λŠ” λͺ¨λ“  클래슀 μƒμ†κ³„μΈ΅λ„μ˜ μ΅œμƒμœ„μ— μžˆλŠ” μ‘°μƒν΄λž˜μŠ€
λ‹€λ₯Έ ν΄λž˜μŠ€λ‘œλΆ€ν„° 상속을 λ°›λŠ”λ‹€κ³  ν•˜λ”λΌλ„ 상속계측도λ₯Ό 따라 μ‘°μƒν΄λž˜μŠ€, μ‘°μƒν΄λž˜μŠ€μ˜ μ‘°μƒν΄λž˜μŠ€λ₯Ό μ°Ύμ•„ μ˜¬λΌκ°€λ‹€ 보면 κ²°κ΅­ λ§ˆμ§€λ§‰ μ΅œμƒμœ„ 쑰상은 Object클래슀일 것이닀.

# Reference & Additional Resources

Last Updated: 12/5/2020, 11:36:44 AM