Skip to content

Latest commit

Β 

History

History
68 lines (49 loc) Β· 4.02 KB

Item_18._use_composition_instead_extend.md

File metadata and controls

68 lines (49 loc) Β· 4.02 KB

Item 18. 상속 λŒ€μ‹  μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©ν•˜λΌ

μƒμ†μ˜ μœ„ν—˜μ„±

상속

class MySet<E> extends HashSet<E> {

    @Override
    public int size() {
        return super.size();
    }

}

상속은 μΊ‘μŠν™”λ₯Ό 깨트림

  • μƒμœ„ 클래슀의 λ‚΄λΆ€ κ΅¬ν˜„μ΄ λ‹¬λΌμ‘Œμ„ λ•Œ, 이 클래슀의 APIλ§Œμ„ μ΄μš©ν•˜λŠ” μ™ΈλΆ€ ν΄λΌμ΄μ–ΈνŠΈλŠ” 영ν–₯을 받지 μ•ŠμŒ
  • κ·ΈλŸ¬λ‚˜ 이λ₯Ό μƒμ†ν•˜λŠ” ν•˜μœ„ ν΄λž˜μŠ€λŠ”, λ‚΄λΆ€ κ΅¬ν˜„ 변경에 μ˜ν•΄ 영ν–₯을 받을 수 있음
    • μ™œ? ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œλŠ” μƒμœ„ 클래슀λ₯Ό μ˜€λ²„λΌμ΄λ”©ν•  수 있고, μƒμœ„ ν΄λž˜μŠ€μ—μ„œ λ‚΄λΆ€ κ΅¬ν˜„ 상 λ‚΄λΆ€μ˜ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” κ³Όμ •μ—μ„œ λ‹€λ₯Έ λ‚΄λΆ€ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ²Œ 되면 μ˜€λ²„λΌμ΄λ”©λœ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ²Œ 됨
    • λ”°λΌμ„œ μžκΈ°μ‚¬μš©(self-use) 여뢀에 따라 λ™μž‘μ΄ λ‹¬λΌμ§ˆ 수 있으며, μ΄λŠ” λ‚΄λΆ€ κ΅¬ν˜„ 방식에 ν•΄λ‹Ή
  • λ˜ν•œ, μƒμœ„ ν΄λž˜μŠ€μ— μƒˆλ‘œμš΄ λ©”μ„œλ“œκ°€ μΆ”κ°€λ˜κ±°λ‚˜ ν•˜λŠ” 이유둜 λ™μž‘μ΄ λ‹¬λΌμ§ˆ 수 있음

ν•΄κ²°μ±…κ³Ό λ’€λ”°λ₯΄λŠ” λ¬Έμ œμ λ“€

  • μƒμœ„ 클래슀의 λ©”μ„œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ”©ν•˜λŠ” κ³Όμ •μ—μ„œ superλ₯Ό ν˜ΈμΆœν•˜λŠ” λŒ€μ‹  μ•„μ˜ˆ λ™μž‘ 자체λ₯Ό μž¬μ •μ˜ν•  수 μžˆμœΌλ‚˜, μ΄λŠ” λ³΅μž‘ν•˜κ³  μ„±λŠ₯ μ €ν•˜λ₯Ό μΌμœΌν‚¬ 수 있음
  • μ•„μ˜ˆ μ΄λ¦„λ§Œ κ°™κ³  λ°˜ν™˜ νƒ€μž…/맀개 μΈμžκ°€ λ‹€λ₯Έ λ©”μ„œλ“œλ₯Ό μƒˆλ‘œ μ„ μ–Έν•  수 μžˆμœΌλ‚˜, 이 μ—­μ‹œ μ•„λž˜μ˜ λ¬Έμ œμ λ“€μ„ μ•ΌκΈ°
    • μƒμœ„ 클래슀의 μƒˆ λ¦΄λ¦¬μŠ€μ— μ‹œκ·Έλ‹ˆμ²˜κ°€ κ°™κ³  λ°˜ν™˜ νƒ€μž…μ΄ λ‹€λ₯Έ λ©”μ„œλ“œκ°€ 좔가됨 - μƒμ„±ν•œ λ©”μ„œλ“œκ°€ λ¬΄μ‹œλ¨
    • μƒμœ„ 클래슀의 μƒˆ λ¦΄λ¦¬μŠ€μ— μ‹œκ·Έλ‹ˆμ²˜, λ°˜ν™˜ νƒ€μž…μ΄ λͺ¨λ‘ 같은 λ©”μ„œλ“œκ°€ 좔가됨 - λ‹¨μˆœ μ˜€λ²„λΌμ΄λ”©μ²˜λ¦¬λ˜μ–΄ μ˜€λ™μž‘ μœ„ν—˜μ΄ 있음

문제 μš”μΈ

  • ν•˜μœ„ 클래슀의 μž¬μ •μ˜κ°€ μƒμœ„ 클래슀의 λ™μž‘μ—λ„ 영ν–₯을 미치게 되기 λ•Œλ¬Έμ— λ‚΄λΆ€ κ΅¬ν˜„μ— 영ν–₯을 λ°›κ²Œ 됨
  • μƒμœ„ ν΄λž˜μŠ€μ™€ ν•˜μœ„ ν΄λž˜μŠ€λŠ” κ°•ν•˜κ²Œ μ—°κ²°λ˜λ©°, μƒμœ„ 클래슀의 μƒˆ 변경점에 ν•˜μœ„ ν΄λž˜μŠ€λŠ” 큰 영ν–₯을 λ°›μŒ
  • μ΄λŠ” ν•˜μœ„ ν΄λž˜μŠ€κ°€ 사싀은 μƒμœ„ ν΄λž˜μŠ€μ™€ is-a 관계가 μ•„λ‹Œλ° μƒμ†ν•˜κΈ° λ•Œλ¬Έμ— 주둜 λ°œμƒν•˜λŠ” λ¬Έμ œλ“€λ‘œ, μ΄λŸ¬ν•œ κ²½μš°μ—”λŠ” 상속 λŒ€μ‹  μ»΄ν¬μ§€μ…˜(Composition, ν•©μ„±)을 μ΄μš©ν•΄μ•Ό 함

μ»΄ν¬μ§€μ…˜

class MySet<E> implements Set<E> {

    private final Set<E> set;

    // Set μΈν„°νŽ˜μ΄μŠ€μ˜ λ©”μ„œλ“œλ“€μ„ κ΅¬ν˜„
    // ν¬μ›Œλ”© 방식을 이용
    @Override
    public int size() {
        return set.size();
    }

}
  • κΈ°μ‘΄ 클래슀λ₯Ό ν™•μž₯ν•˜λŠ” λŒ€μ‹ , 이 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λ‚΄λΆ€ ν•„λ“œλ‘œ μ°Έμ‘°ν•˜κ²Œ ν•˜λŠ” 섀계
  • μƒˆ ν΄λž˜μŠ€λŠ” κΈ°μ‘΄ 클래슀의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ²Œ 되고, 이λ₯Ό 처리λ₯Ό λ„˜κΈ΄λ‹€λŠ” 의미둜 μœ„μž„(delegation)이라고 뢀름
  • λ˜ν•œ, μƒˆ ν΄λž˜μŠ€λŠ” λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€λ₯Ό κ°μ‹ΈλŠ” 역할을 ν•œλ‹€λŠ” λœ»μ—μ„œ 래퍼(Wrapper) 클래슀라고 뢀름
  • μœ„μ™€ 같이 μ»΄ν¬μ§€μ…˜μ„ μ΄μš©ν•˜λ©΄, Set μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ꡬ체 클래슀λ₯Ό μƒμ†ν•˜λŠ” λŒ€μ‹  μ–΄λ–€ Set의 κΈ°λŠ₯이라도 μœ μ—°ν•˜κ²Œ 이용이 κ°€λŠ₯
  • MySet은 Set에 νŠΉμ •ν•œ κΈ°λŠ₯을 λ§μ”ŒμšΈ 수 μžˆλŠ” ν΄λž˜μŠ€λΌλŠ” μ μ—μ„œ λ°μ½”λ ˆμ΄ν„°(Decorator) νŒ¨ν„΄μ„ μ΄μš©ν–ˆλ‹€κ³  λ³Ό 수 있음

μ–Έμ œ 상속을 μ‚¬μš©?

  • ν•˜μœ„ ν΄λž˜μŠ€κ°€ μƒμœ„ ν΄λž˜μŠ€μ™€ μ •ν™•νžˆ is-a 관계일 λ•Œμ—λ§Œ 상속을 μ΄μš©ν•  수 있음
    • λ¦¬μŠ€μ½”ν”„ μΉ˜ν™˜ 원칙(μ„œλΈŒ νƒ€μž…μ€ μ–Έμ œλ‚˜ 기반 νƒ€μž…μœΌλ‘œ ꡐ체할 수 μžˆμ–΄μ•Ό ν•œλ‹€) μ—μ„œ λ˜ν•œ 이 점을 κ°•μ‘°ν•˜κ³  있음
    • 이λ₯Ό λ§Œμ‘±ν•˜λŠ” 방법은, ν•˜μœ„ 클래슀λ₯Ό μƒμœ„ 클래슀둜 λŒ€μ²΄ν–ˆμ„ λ•Œ λͺ¨λ“  λ™μž‘μ΄ 정상적인가? λ₯Ό 보면 됨
  • κ·ΈλŸ¬λ‚˜ 상속을 μ΄μš©ν•˜λ©΄ ν•˜μœ„ ν΄λž˜μŠ€λŠ” μƒμœ„ 클래슀의 결함을 κ·ΈλŒ€λ‘œ λ¬Όλ €λ°›κ²Œ 되며, μƒμœ„ ν΄λž˜μŠ€κ°€ ν™•μž₯을 κ³ λ €ν•΄ μ„€κ³„λ˜μ§€ μ•Šμ•˜λ‹€λ©΄ μ˜€λ²„λΌμ΄λ”©ν•œ λ©”μ„œλ“œμ— μ˜ν•΄ λ‹€μ–‘ν•œ λ¬Έμ œκ°€ λ°œμƒν•  수 있음
  • λ”°λΌμ„œ 상속 λŒ€μ‹  μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©ν•˜λŠ” 편이 더 μœ μ—°ν•œ 클래슀λ₯Ό μ •μ˜ν•  수 있음