Item 20. Abstract Class & Interface

좔상 ν΄λž˜μŠ€λ³΄λ‹€λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μš°μ„ ν•˜λΌ

Javaμ—μ„œ μ œκ³΅ν•˜λŠ” 닀쀑 κ΅¬ν˜„ λ©”μ»€λ‹ˆμ¦˜μ€ μΈν„°νŽ˜μ΄μŠ€μ™€ 좔상 클래슀λ₯Ό 톡해 μ œκ³΅λœλ‹€. Java 8 μ΄μ „μ—λŠ” μΈν„°νŽ˜μ΄μŠ€λŠ” κ΅¬ν˜„ μ½”λ“œλ₯Ό 포함할 수 μ—†μ—ˆμ§€λ§Œ, Java 8 μ΄ν›„λΆ€ν„°λŠ” μΈν„°νŽ˜μ΄μŠ€λ„ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό 톡해 κ΅¬ν˜„ μ½”λ“œλ₯Ό 포함할 수 있게 λ˜μ—ˆλ‹€. λ•Œλ¬Έμ— Java 8 μ΄ν›„μ—μ„œμ˜ 두 λ°©μ‹μ˜ 큰 μ°¨μ΄λŠ” μ•„λž˜μ™€ κ°™λ‹€.

  • 좔상 클래슀: 좔상 ν΄λž˜μŠ€κ°€ μ •μ˜ν•œ νƒ€μž…μ„ κ΅¬ν˜„ν•œ ν΄λž˜μŠ€λŠ” λ°˜λ“œμ‹œ 좔상 클래슀의 ν•˜μœ„ ν΄λž˜μŠ€κ°€ λ˜μ–΄μ•Ό ν•œλ‹€.

  • μΈν„°νŽ˜μ΄μŠ€: μΈν„°νŽ˜μ΄μŠ€κ°€ μ„ μ–Έν•œ λ©”μ„œλ“œλ₯Ό λͺ¨λ‘ μ •μ˜ν•˜κ³  κ·Έ 일반 κ·œμ•½μ„ 잘 지킀면 λ‹€λ₯Έ 클래슀λ₯Ό μƒμ†ν–ˆλ“  상관없이 같은 νƒ€μž…μœΌλ‘œ μ·¨κΈ‰λœλ‹€.

ν•œλ§ˆλ””λ‘œ μΈν„°νŽ˜μ΄μŠ€λŠ” 좔상 ν΄λž˜μŠ€μ™€ 달리 닀쀑 κ΅¬ν˜„μ΄ κ°€λŠ₯ν•˜λ‹€λŠ” 차이가 μ‘΄μž¬ν•œλ‹€. (좔상 ν΄λž˜μŠ€λŠ” Class cannot extend multiple classes μ—λŸ¬ λ°œμƒ) λ§Œμ•½ κΈ°μ‘΄ ν΄λž˜μŠ€μ— κΈ°λŠ₯을 μΆ”κ°€ν•˜κΈ° μœ„ν•΄μ„ , μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν΄λž˜μŠ€κ°€ 훨씬 손 μ‰½κ²Œ κΈ°λŠ₯을 μΆ”κ°€ν•  수 μžˆλ‹€.

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

mixin(믹슀인) μ •μ˜

** 믹슀인: ν΄λž˜μŠ€κ°€ κ΅¬ν˜„ν•  수 μžˆλŠ” νƒ€μž…μœΌλ‘œ, λ―ΉμŠ€μΈμ„ κ΅¬ν˜„ν•œ ν΄λž˜μŠ€μ— μ›λž˜μ˜ 주된 νƒ€μž… 외에도 νŠΉμ • 선택적 ν–‰μœ„λ₯Ό ν˜Όν•©ν•  수 있게 ν•΄μ€€λ‹€.

μœ„ νŠΉμ§• λ•Œλ¬Έμ— μΈν„°νŽ˜μ΄μŠ€λŠ” 기쑴의 μ£Όμš” κΈ°λŠ₯에 선택적 κΈ°λŠ₯을 μΆ”κ°€ν•  수 μžˆλŠ” λ―ΉμŠ€μΈμ„ μ •μ˜ν•˜λŠ” μš©λ„λ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.

interface A {
    // ..
}

interface B {
    // ..
}

// ..

class ImplementClass implements A, B { // C, D, ...
    // ..
}

계측 ꡬ쑰 μ—†λŠ” νƒ€μž… ν”„λ ˆμž„μ›Œν¬ μ •μ˜

계측 κ΅¬μ‘°λŠ” μˆ˜λ§Žμ€ κ°œλ…μ„ ꡬ쑰적으둜 잘 ν‘œν˜„ν•  수 μžˆμ§€λ§Œ, ν˜„μ‹€μ˜ κ°œλ°œμ—μ„œλŠ” κ΅¬λΆ„ν•˜κΈ° νž˜λ“  κ°œλ…μ΄ λ§Žλ‹€. 계측 ꡬ쑰둜 λͺ¨λ“  κ°œλ…μ„ ν¬κ΄„ν•˜κΈ° μœ„ν•΄μ„  μ§€λ‚˜μΉ˜κ²Œ 많고 λ³΅μž‘ν•œ ꡬ쑰가 μƒκΈ°κ²Œ λ˜μ–΄ μœ μ§€λ³΄μˆ˜κ°€ μ–΄λ €μ›Œμ§„λ‹€. λ•Œλ¬Έμ— 좔상 ν΄λž˜μŠ€μ™€λŠ” 달리 μΈν„°νŽ˜μ΄μŠ€λŠ” 닀쀑 κ΅¬ν˜„μ΄ κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— μ² μ €ν•œ 계측 ꡬ쑰 없이 μœ μ—°ν•˜κ²Œ νƒ€μž…μ„ μ •μ˜ν•  수 μžˆλ‹€.

interface Singer {
    void sing();
}

interface Songwriter {
    void compose();
}

interface SingerSongwriter extends Singer, Songwriter {
    void strum();

    void actSensitive();
}

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

Java 8λΆ€ν„° μΈν„°νŽ˜μ΄μŠ€μ— default λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  수 있게 λ˜μ—ˆλ‹€. 이 κΈ°λŠ₯으둜 인해 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν΄λž˜μŠ€λ“€μ΄ μƒˆλ‘œμš΄ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€λŠ” μž₯점이 μƒκ²Όμ§€λ§Œ 이 κΈ°λŠ₯을 λ‚¨μš©ν•˜λ©΄ μ•ˆλ˜λ©° μ•„λž˜μ˜ 사항듀을 염두해야 ν•œλ‹€.

  • @implSpec을 ν†΅ν•œ λ¬Έμ„œν™”ν•˜μ—¬ ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 정보 제곡

  • equals, hashCode, toString λ“±μ˜ λ©”μ„œλ“œλŠ” default λ©”μ„œλ“œλ‘œ 제곡 κΈˆμ§€

    • 객체의 κΈ°λ³Έ λ™μž‘ 및 객체의 식별성에 영ν–₯을 μ£Όμ–΄, κ΅¬ν˜„ ν΄λž˜μŠ€μ—μ„œ μ΄λŸ¬ν•œ λ©”μ„œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ“œν•˜μ§€ μ•Šκ³  κ·ΈλŒ€λ‘œ μ‚¬μš©ν•  경우 잘λͺ»λœ λ™μž‘μ„ 유발 κ°€λŠ₯

  • μΈμŠ€ν„΄μŠ€ ν•„λ“œλ₯Ό κ°€μ§ˆ 수 μ—†μŒ

  • private static λ©”μ„œλ“œλ₯Ό μ œμ™Έν•œ private 멀버 μ‚¬μš© λΆˆκ°€λŠ₯

λ§Œμ•½ μœ„μ˜ 단점이 κ΅¬ν˜„ 사항에 영ν–₯을 주지 μ•ŠλŠ”λ‹€λ©΄ κ°€λŠ₯ν•œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹μœΌλ©°, λ§Œμ•½ κ΅¬ν˜„ 사항에 μ œμ•½μ΄ κ±Έλ¦¬λŠ” 경우 μ•„λž˜μ—μ„œ μ†Œκ°œν•  방법을 κ³ λ €ν•΄λ³Ό 수 μžˆλ‹€.

Skeletal Implementation(좔상 골격 κ΅¬ν˜„)

μΈν„°νŽ˜μ΄μŠ€μ™€ 좔상 클래슀의 μž₯점을 λͺ¨λ‘ κ°€μ§€λŠ” λ°©λ²•μœΌλ‘œ μΈν„°νŽ˜μ΄μŠ€ + 좔상 골격 κ΅¬ν˜„ 클래슀λ₯Ό ν•¨κ»˜ μ œκ³΅ν•˜λŠ” 방법이 μžˆλ‹€. 이λ₯Ό ν…œν”Œλ¦Ώ λ©”μ„œλ“œ νŒ¨ν„΄μ΄λΌκ³  ν•˜λ©°, 각각의 역할은 μ•„λž˜μ™€ κ°™λ‹€.

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

    • νƒ€μž… μ •μ˜

    • ν•„μš”ν•œ 경우 λ””ν΄νŠΈ λ©”μ„œλ“œλ„ 제곡

  • 좔상 골격 κ΅¬ν˜„ 클래슀

    • λ‚˜λ¨Έμ§€ λ©”μ„œλ“œλ“€μ„ κ΅¬ν˜„

μ΄λŸ¬ν•œ 사둀λ₯Ό JDKμ—μ„œλ„ 많이 λ³Ό 수 μžˆλŠ”λ°, λŒ€ν‘œμ μœΌλ‘œ AbstractList 이 μžˆλ‹€.

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {

    // μΈν„°νŽ˜μ΄μŠ€μ˜ λ©”μ„œλ“œ κ΅¬ν˜„, μ—λŸ¬λ₯Ό λ°œμƒμ‹œμΌœ ν•˜μœ„ ν΄λž˜μŠ€κ°€ μ˜€λ²„λΌμ΄λ“œν•˜λ„λ‘ μœ λ„
    public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

    // ν•„μš”ν•œ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλ„λ‘ κ΅¬ν˜„
    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof List))
            return false;

        ListIterator<E> e1 = listIterator();
        ListIterator<?> e2 = ((List<?>) o).listIterator();
        while (e1.hasNext() && e2.hasNext()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1 == null ? o2 == null : o1.equals(o2)))
                return false;
        }
        return !(e1.hasNext() || e2.hasNext());
    }

    public int hashCode() {
        int hashCode = 1;
        for (E e : this)
            hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
        return hashCode;
    }
}

equals와 hashCodeλ₯Ό List μΈν„°νŽ˜μ΄μŠ€μ˜ 일반 κ·œμ•½μ„ μ§€μΌœμ„œ μ œκ³΅ν•˜μ˜€κ³ , λ‚˜λ¨Έμ§€ λ©”μ„œλ“œλ“€μ€ ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ μ˜€λ²„λΌμ΄λ“œν•˜λ„λ‘ μœ λ„ν•˜μ—¬ κ΅¬ν˜„μ„ κ°•μ œν•˜μ˜€λ‹€. 결과적으둜 좔상 클래슀처럼 κ΅¬ν˜„μ„ λ„μ™€μ£ΌλŠ” λ™μ‹œμ—, 닀쀑 κ΅¬ν˜„μ΄ κ°€λŠ₯ν•œ μΈν„°νŽ˜μ΄μŠ€μ˜ μž₯점도 λͺ¨λ‘ κ°€μ§€κ²Œ λœλ‹€.

Last updated

Was this helpful?