πŸ‘¨πŸ»β€πŸ’» μ΄νŽ™ν‹°λΈŒ μžλ°” - ν΄λž˜μŠ€μ™€ μΈν„°νŽ˜μ΄μŠ€

PeterΒ·2022λ…„ 3μ›” 20일
0
post-thumbnail

4μž₯ - ν΄λž˜μŠ€μ™€ μΈν„°νŽ˜μ΄μŠ€


πŸ’‘ ν΄λž˜μŠ€μ™€ λ©€λ²„μ˜ μ ‘κ·Ό κΆŒν•œμ„ μ΅œμ†Œν™”ν•˜λΌ

β€œμ ‘κ·Ό κΆŒν•œμ„ κ°€λŠ₯ν•œ ν•œ μ’νžˆμžβ€

1. 정보 은닉(μΊ‘μŠν™”)

  • μ–΄μ„€ν”„κ²Œ μ„€κ³„λœ μ»΄ν¬λ„ŒνŠΈμ™€ 잘 μ„€κ³„λœ μ»΄ν¬λ„ŒνŠΈμ˜ κ°€μž₯ 큰 μ°¨μ΄λŠ” λ°”λ‘œ
    β€œν΄λž˜μŠ€ λ‚΄λΆ€ 데이터와 λ‚΄λΆ€ κ΅¬ν˜„ 정보λ₯Ό μ™ΈλΆ€ μ»΄ν¬λ„ŒνŠΈλ‘œλΆ€ν„° μ–Όλ§ˆλ‚˜ 잘 μˆ¨κ²ΌλŠλƒβ€λ‹€.
  • 잘 μ„€κ³„λœ μ»΄ν¬λ„ŒνŠΈλŠ” λͺ¨λ“  λ‚΄λΆ€ κ΅¬ν˜„μ„ μ™„λ²½νžˆ 숨기며 였직 APIλ₯Ό ν†΅ν•΄μ„œ λ‹€λ₯Έ μ»΄ν¬λ„ŒνŠΈμ™€ μ†Œν†΅ν•¨. β†’ 정보은닉(μΊ‘μŠν™”)
  • 정보 μ€λ‹‰μ˜ μž₯점
    • μ»΄ν¬λ„ŒνŠΈλ₯Ό λ³‘λ ¬λ‘œ κ°œλ°œν•  수 있음 β†’ μ‹œμŠ€ν…œ 개발 속도↑
    • μ»΄ν¬λ„ŒνŠΈ ꡐ체 뢀담↓ β†’ μ‹œμŠ€ν…œ 관리 λΉ„μš©β†“
    • 외뢀에 거의 μ˜μ‘΄ν•˜μ§€ μ•Šκ³  λ…μžμ μœΌλ‘œ λ™μž‘ν•  수 μžˆλŠ” μ»΄ν¬λ„ŒνŠΈ β†’ μ†Œν”„νŠΈμ›¨μ–΄ μž¬μ‚¬μš©μ„±β†‘
    • μ‹œμŠ€ν…œ 전체가 μ™„μ„±λ˜μ§€ μ•Šμ•˜μ–΄λ„ κ°œλ³„ μ»΄ν¬λ„ŒνŠΈ λ™μž‘ 검증 κ°€λŠ₯ β†’ μ‹œμŠ€ν…œ μ œμž‘ λ‚œμ΄λ„β†“
  • μžλ°”μ—μ„œ 정보 은닉을 μœ„ν•œ μž₯치 β†’ μ ‘κ·Ό μ œμ–΄ λ©”μ»€λ‹ˆμ¦˜ : μ ‘κ·Ό μ œν•œμž ν™œμš©

2. 멀버에 λΆ€μ—¬ν•  수 μžˆλŠ” 4가지 μ ‘κ·Ό μ œν•œμž

μ ‘κ·Ό μ œν•œμžμ„€λͺ…
private멀버λ₯Ό μ„ μ–Έν•œ ν†±λ ˆλ²¨ ν΄λž˜μŠ€μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆλ‹€.
package-private멀버가 μ†Œμ†λœ νŒ¨ν‚€μ§€ μ•ˆμ˜ λͺ¨λ“  ν΄λž˜μŠ€μ—μ„œ μ ‘κ·Όν•  수 μžˆλ‹€. μ ‘κ·Ό μ œν•œμžλ₯Ό λͺ…μ‹œν•˜μ§€ μ•Šμ•˜μ„ λ•Œ μ μš©λ˜λŠ” νŒ¨ν‚€μ§€ μ ‘κ·Όμˆ˜μ€€μ΄λ‹€(단, μΈν„°νŽ˜μ΄μŠ€μ˜ λ©€λ²„λŠ” 기본적으둜 public이 μ μš©λœλ‹€).
protectedpackage-private의 μ ‘κ·Ό λ²”μœ„λ₯Ό ν¬ν•¨ν•˜λ©°, 이 멀버λ₯Ό μ„ μ–Έν•œ 클래슀의 ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œλ„ μ ‘κ·Όν•  수 μžˆλ‹€.
publicλͺ¨λ“  κ³³μ—μ„œ μ ‘κ·Όν•  수 μžˆλ‹€.
  • protected와 public은 곡개 APIμž„

3. public static final

  • ν•΄λ‹Ή ν΄λž˜μŠ€κ°€ ν‘œν˜„ν•˜λŠ” 좔상 κ°œλ…μ„ μ™„μ„±ν•˜λŠ” 데 κΌ­ ν•„μš”ν•œ μƒμˆ˜λΌλ©΄ public static final둜 κ³΅κ°œν•΄λ„ μ’‹μŒ
    • 관둀상 이름은 μ•ŒνŒŒλ²³ λŒ€λ¬Έμžμ™€ 밑쀄(_)둜 λ§Œλ“ λ‹€. ex) TEST_VALUE
    • 이런 ν•„λ“œλŠ” λ°˜λ“œμ‹œ κΈ°λ³Ένƒ€μž… κ°’μ΄λ‚˜ λΆˆλ³€κ°μ²΄λ₯Ό μ°Έμ‘°ν•΄μ•Ό 함.
      • 길이가 0이 μ•„λ‹Œ 배열은 λͺ¨λ‘ 가변인 점을 μ£Όμ˜ν•˜μž!
  • 이 경우 이외에 public ν΄λž˜μŠ€λŠ” μ–΄λ– ν•œ public ν•„λ“œλ„ 가지면 μ•ˆ 됨.


πŸ’‘ public ν΄λž˜μŠ€μ—μ„œλŠ” public ν•„λ“œκ°€ μ•„λ‹Œ μ ‘κ·Όμž λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λΌ

β€œν•„λ“œλ“€μ„ λͺ¨λ‘ private으둜 λ°”κΎΈκ³ , μ ‘κ·Όμž(getter)λ₯Ό μ œκ³΅ν•˜μžβ€

1. ν‡΄λ³΄ν•œ 클래슀

class Point {
    public double x;
    public double y;
}
  • 데이터 ν•„λ“œμ— 직접 μ ‘κ·Ό κ°€λŠ₯ν•˜λ―€λ‘œ μΊ‘μŠν™”μ˜ 이점 제곡 λΆˆκ°€
  • APIλ₯Ό μˆ˜μ •ν•˜μ§€ μ•Šκ³ λŠ” λ‚΄λΆ€ ν‘œν˜„ λ³€κ²½ λΆˆκ°€
  • μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  λ•Œ λΆ€μˆ˜ μž‘μ—… μˆ˜ν–‰ λΆˆκ°€

2. μΊ‘μŠν™”

// μ ‘κ·Όμžμ™€ λ³€κ²½μž(mutator) λ©”μ„œλ“œλ₯Ό ν™œμš©ν•΄ 데이터λ₯Ό μΊ‘μŠν™”ν•œλ‹€.
class Point {
    private double x;
    private double y;

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() { return x; }
    public double getY() { return y; }

    public void setX(double x) { this.x = x; }
    public void setY(double y) { this.y = y; }
}
  • 클래슀 λ‚΄λΆ€ ν‘œν˜„ μ–Έμ œλ“  λ³€κ²½ κ°€λŠ₯ β†’ μœ μ—°μ„±β†‘


πŸ’‘ λ³€κ²½ κ°€λŠ₯성을 μ΅œμ†Œν™”ν•˜λΌ

β€œν΄λž˜μŠ€λŠ” κΌ­ ν•„μš”ν•œ κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ λΆˆλ³€μ΄μ–΄μ•Ό 함”

1. λΆˆλ³€ 클래슀

  • μΈμŠ€ν„΄μŠ€ λ‚΄λΆ€ 값을 μˆ˜μ •ν•  수 μ—†λŠ” 클래슀, 객체가 νŒŒκ΄΄λ˜λŠ” μˆœκ°„κΉŒμ§€ μ ˆλŒ€ 달라지지 μ•ŠμŒ
  • ex) String, BigInteger, BigDecimal λ“±
  • λΆˆλ³€ ν΄λž˜μŠ€λŠ” κ°€λ³€ ν΄λž˜μŠ€λ³΄λ‹€ 섀계/κ΅¬ν˜„ 및 μ‚¬μš©μ΄ μ‰¬μš°λ©°, 였λ₯˜κ°€ 생길 여지도 적고 훨씬 μ•ˆμ „ν•¨

2. λΆˆλ³€ 클래슀λ₯Ό λ§Œλ“€κΈ° μœ„ν•œ 5가지 κ·œμΉ™

1) 객체의 μƒνƒœλ₯Ό λ³€κ²½ν•˜λŠ” λ©”μ„œλ“œ(λ³€κ²½μž)λ₯Ό μ œκ³΅ν•˜μ§€ μ•ŠλŠ”λ‹€.

2) 클래슀λ₯Ό ν™•μž₯ν•  수 없도둝 ν•œλ‹€.

  • ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ λΆ€μ£Όμ˜ν•˜κ²Œ 객체의 μƒνƒœλ₯Ό λ³€ν•˜κ²Œ λ§Œλ“œλŠ” μ‚¬νƒœ 방지.

3) λͺ¨λ“  ν•„λ“œλ₯Ό final둜 μ„ μ–Έν•œλ‹€.

4) λͺ¨λ“  ν•„λ“œλ₯Ό private으둜 μ„ μ–Έν•œλ‹€.

5) μžμ‹  μ™Έμ—λŠ” λ‚΄λΆ€μ˜ κ°€λ³€ μ»΄ν¬λ„ŒνŠΈμ— μ ‘κ·Όν•  수 없도둝 ν•œλ‹€.

  • μ ‘κ·Όμž λ©”μ„œλ“œκ°€ κ·Έ ν•„λ“œλ₯Ό κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•˜κ²Œ ν•˜λ©΄ μ•ˆ 됨.
  • μƒμ„±μž, μ ‘κ·Όμž, readObject λ©”μ„œλ“œ λͺ¨λ‘μ—μ„œ 방어적 볡사λ₯Ό μˆ˜ν–‰ν•˜μž.

3. λΆˆλ³€ 객체의 μž₯점

  • λ‹¨μˆœν•¨
    • λΆˆλ³€ κ°μ²΄λŠ” μƒμ„±λœ μ‹œμ μ˜ μƒνƒœλ₯Ό 파괴될 λ•ŒκΉŒμ§€ κ·ΈλŒ€λ‘œ 간직함.
    • κ°€λ³€ κ°μ²΄λŠ” μž„μ˜μ˜ λ³΅μž‘ν•œ μƒνƒœμ— 놓일 수 있음.
  • 근본적으둜 μŠ€λ ˆλ“œ μ•ˆμ „ν•˜μ—¬ λ”°λ‘œ 동기화할 ν•„μš” μ—†μŒ
  • λΆˆλ³€ 객체끼리 λ‚΄λΆ€ 데이터 곡유 κ°€λŠ₯
  • 객체λ₯Ό λ§Œλ“€ λ•Œ λ‹€λ₯Έ λΆˆλ³€ 객체듀을 κ΅¬μ„±μš”μ†Œλ‘œ μ‚¬μš©ν•˜λ©΄ νŽΈλ¦¬ν•¨
  • κ·Έ 자체둜 μ‹€νŒ¨ μ›μžμ„±μ„ μ œκ³΅ν•¨
    • μƒνƒœκ°€ μ ˆλŒ€ λ³€ν•˜μ§€ μ•ŠμœΌλ‹ˆ 뢈일치 μƒνƒœμ— 빠질 κ°€λŠ₯성이 μ—†μŒ

4. λΆˆλ³€ 객체의 단점

  • 값이 λ‹€λ₯΄λ©΄ λ°˜λ“œμ‹œ λ…λ¦½λœ 객체둜 λ§Œλ“€μ–΄μ•Ό 함
    • κ°’μ˜ κ°€μ§“μˆ˜κ°€ λ§Žλ‹€λ©΄ 큰 λΉ„μš©μ„ μΉ˜λŸ¬μ•Ό 함

5. 변경을 μ΅œμ†Œν™” ν•˜μž

  • ν΄λž˜μŠ€λŠ” κΌ­ ν•„μš”ν•œ κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ λΆˆλ³€μ΄μ–΄μ•Ό 함
  • λΆˆλ³€μœΌλ‘œ λ§Œλ“€ 수 μ—†λŠ” ν΄λž˜μŠ€λΌλ„ λ³€κ²½κ°€λŠ₯ν•œ 뢀뢄을 μ΅œμ†Œν•œμœΌλ‘œ μ€„μ΄μž
  • λ‹€λ₯Έ ν•©λ‹Ήν•œ μ΄μœ κ°€ μ—†λ‹€λ©΄ λͺ¨λ“  ν•„λ“œλŠ” private final이어야 함
  • μƒμ„±μžλŠ” λΆˆλ³€μ‹ 섀정이 λͺ¨λ‘ μ™„λ£Œλœ, μ΄ˆκΈ°ν™”κ°€ μ™„λ²½νžˆ λλ‚œ μƒνƒœμ˜ 객체λ₯Ό 생성해야 함


πŸ’‘ μƒμ†λ³΄λ‹€λŠ” μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©ν•˜λΌ

β€œμ»΄ν¬μ§€μ…˜κ³Ό 전달을 잘 ν™œμš©ν•˜μžβ€

1. μƒμ†μ˜ 문제점

  • 상속은 μΊ‘μŠν™”λ₯Ό κΉ¨λœ¨λ¦°λ‹€.
    • μƒμœ„ ν΄λž˜μŠ€λŠ” λ¦΄λ¦¬μŠ€λ§ˆλ‹€ λ‚΄λΆ€ κ΅¬ν˜„μ΄ λ‹¬λΌμ§ˆ 수 있으며, κ·Έ μ—¬νŒŒλ‘œ μ½”λ“œ ν•œ 쀄 κ±΄λ“œλ¦¬μ§€ μ•Šμ€ ν•˜μœ„ ν΄λž˜μŠ€κ°€ μ˜€λ™μž‘ν•  수 있음.
    • λ‹€μŒ λ¦΄λ¦¬μŠ€μ—μ„œ μƒμœ„ ν΄λž˜μŠ€μ— μƒˆλ‘œ μΆ”κ°€λœ λ©”μ„œλ“œκ°€ ν•˜μœ„ν΄λž˜μŠ€μ˜ λ©”μ„œλ“œμ™€ μ‹œκ·Έμ²˜κ°€ κ°™κ³  λ°˜ν™˜νƒ€μž…μ΄ λ‹€λ₯΄λ‹€λ©΄? β†’ ν•΄λ‹Ή ν΄λž˜μŠ€λŠ” 컴파일쑰차 λ˜μ§€ μ•ŠμŒ
  • 상속 잘λͺ»λœ μ˜ˆμ‹œ μ½”λ“œ
// 잘λͺ»λœ 예 - 상속을 잘λͺ» μ‚¬μš©ν–ˆλ‹€!
public class InstrumentedHashSet<E> extends HashSet<E> {
    // μΆ”κ°€λœ μ›μ†Œμ˜ 수
    private int addCount = 0;

    public InstrumentedHashSet() {
    }

    public InstrumentedHashSet(int initCap, float loadFactor) {
        super(initCap, loadFactor);
    }

    @Override public boolean add(E e) {
        addCount++;
        return super.add(e);
    }

    @Override public boolean addAll(Collection<? extends E> c) {
        addCount += c.size();
        return super.addAll(c);
    }

    public int getAddCount() {
        return addCount;
    }

    public static void main(String[] args) {
        InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
        s.addAll(List.of("ν‹±", "탁탁", "νŽ‘"));
        System.out.println(s.getAddCount());
    }
}-

β†’ main λ©”μ„œλ“œκ°€ μ‹€ν–‰λ˜λ©΄ 숫자 λͺ‡μ΄ 좜λ ₯ 될까?

  • μ›μ†Œ 3κ°œκ°€ μΆ”κ°€λ˜μ—ˆμœΌλ‹ˆ μ˜λ„λŒ€λ‘œ 3κ°œκ°€ 좜λ ₯될 것이라 κΈ°λŒ€ν•˜κ² μ§€λ§Œ, μ‹€μ œλ‘œλŠ” 6을 좜λ ₯함
  • μ΄μœ λŠ” HashSet의 addAll λ©”μ„œλ“œκ°€ λ‚΄λΆ€μ—μ„œ add λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κΈ° λ•Œλ¬Έ(self-use; μžκΈ°μ‚¬μš©).
  • λ”°λΌμ„œ super.addAllλ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜μ—ˆμ„ λ•Œ, InstrumentedHashSet의 add λ©”μ„œλ“œκ°€ 3번 호좜되기 λ•Œλ¬Έμ— 6이 좜λ ₯ 됨.
  • 상속을 κΌ­ μ‚¬μš©ν•˜κ³  μ‹Άλ‹€λ©΄?
    • 클래슀 Aλ₯Ό μƒμ†ν•˜λŠ” 클래슀 Bλ₯Ό μž‘μ„±ν•˜λ € ν•œλ‹€λ©΄ β€œB is a A”인지λ₯Ό 따져봐야 함.
    • κ·ΈλŸ¬λ‚˜ B is a A이더라도 Aκ°€ ν™•μž₯을 κ³ λ €ν•΄ 섀계 λ˜μ§€ μ•Šμ•˜λ‹€λ©΄ λ¬Έμ œκ°€ 될 수 있음.

2. μ»΄ν¬μ§€μ…˜κ³Ό 전달

β†’ μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©ν•΄ μƒμ†μ˜ 문제λ₯Ό ν”Όν•˜μž

  • μ»΄ν¬μ§€μ…˜(composition) μ„€κ³„λž€?
    • κΈ°μ‘΄ 클래슀λ₯Ό ν™•μž₯ν•˜λŠ” λŒ€μ‹ , μƒˆλ‘œμš΄ 클래슀λ₯Ό λ§Œλ“€κ³  private ν•„λ“œλ‘œ κΈ°μ‘΄ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•˜κ²Œ ν•˜λŠ” 방식.
  • 전달(forwarding)μ΄λž€?
    • μƒˆ 클래슀(전달 클래슀)의 λ©”μ„œλ“œ(전달 λ©”μ„œλ“œ)듀이 κΈ°μ‘΄ ν΄λž˜μŠ€μ— λŒ€μ‘ν•˜λŠ” λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” 방식
  • μ»΄ν¬μ§€μ…˜κ³Ό 전달방식을 μ‚¬μš©ν•˜λ©΄ μƒˆ ν΄λž˜μŠ€λŠ” κΈ°μ‘΄ 클래슀의 λ‚΄λΆ€ κ΅¬ν˜„ λ°©μ‹μ˜ 영ν–₯μ—μ„œ λ²—μ–΄λ‚˜λ©°, 심지어 κΈ°μ‘΄ ν΄λž˜μŠ€μ— μƒˆλ‘œμš΄ λ©”μ„œλ“œκ°€ μΆ”κ°€λ˜λ”λΌλ„ μ „ν˜€ 영ν–₯받지 μ•ŠμŒ
  • μ»΄ν¬μ§€μ…˜κ³Ό 전달 방식 μ˜ˆμ‹œ μ½”λ“œ
  1. 전달 클래슀
// μž¬μ‚¬μš©ν•  수 μžˆλŠ” 전달 클래슀
public class ForwardingSet<E> implements Set<E> {
    private final Set<E> s;
    public ForwardingSet(Set<E> s) { this.s = s; }

    public void clear()               { s.clear();            }
    public boolean contains(Object o) { return s.contains(o); }
    public boolean isEmpty()          { return s.isEmpty();   }
    public int size()                 { return s.size();      }
    public Iterator<E> iterator()     { return s.iterator();  }
    public boolean add(E e)           { return s.add(e);      }
    public boolean remove(Object o)   { return s.remove(o);   }
    public boolean containsAll(Collection<?> c)
                                   { return s.containsAll(c); }
    public boolean addAll(Collection<? extends E> c)
                                   { return s.addAll(c);      }
    public boolean removeAll(Collection<?> c)
                                   { return s.removeAll(c);   }
    public boolean retainAll(Collection<?> c)
                                   { return s.retainAll(c);   }
    public Object[] toArray()          { return s.toArray();  }
    public <T> T[] toArray(T[] a)      { return s.toArray(a); }
    @Override public boolean equals(Object o)
                                       { return s.equals(o);  }
    @Override public int hashCode()    { return s.hashCode(); }
    @Override public String toString() { return s.toString(); }
}
  1. 래퍼 클래슀
// 래퍼 클래슀 - 상속 λŒ€μ‹  μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©
public class InstrumentedSet<E> extends ForwardingSet<E> {
    private int addCount = 0;

    public InstrumentedSet(Set<E> s) {
        super(s);
    }

    @Override public boolean add(E e) {
        addCount++;
        return super.add(e);
    }
    @Override public boolean addAll(Collection<? extends E> c) {
        addCount += c.size();
        return super.addAll(c);
    }
    public int getAddCount() {
        return addCount;
    }

    public static void main(String[] args) {
        InstrumentedSet<String> s = new InstrumentedSet<>(new HashSet<>());
        s.addAll(List.of("ν‹±", "탁탁", "νŽ‘"));
        System.out.println(s.getAddCount());
    }
}

β†’ main λ©”μ„œλ“œκ°€ μ‹€ν–‰λ˜λ©΄ 숫자 λͺ‡μ΄ 좜λ ₯ 될까?

  • μ΄λ²ˆμ—λŠ” μ˜λ„λŒ€λ‘œ 3이 좜λ ₯됨
  • super.addAll λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜μ—ˆμ„ λ•Œ, InstrumentedSet의 add λ©”μ„œλ“œκ°€ μ•„λ‹Œ μ „λ‹¬ν΄λž˜μŠ€μ— μ‘΄μž¬ν•˜λŠ” sμΈμŠ€ν„΄μŠ€μ˜ add λ©”μ„œλ“œκ°€ 호좜되기 λ•Œλ¬Έμ— μ •μƒμ μœΌλ‘œ λ™μž‘ν•¨.
  • 상속 μ˜ˆμ‹œμ—μ„œ λ°œμƒν–ˆλ˜ λ¬Έμ œκ°€ 해결됨.


πŸ’‘ 상속을 κ³ λ €ν•΄ μ„€κ³„ν•˜κ³  λ¬Έμ„œν™”ν•˜λΌ. κ·ΈλŸ¬μ§€ μ•Šμ•˜λ‹€λ©΄ 상속을 κΈˆμ§€ν•˜λΌ

β€œκΌ­ ν•„μš”ν•œ κ²½μš°μ—λ§Œ 상속가λŠ₯ν•˜λ„λ‘ 섀계, λ‚˜λ¨Έμ§€ κ²½μš°μ—” μƒμ†κΈˆμ§€β€

1. μƒμ†μš© 클래슀

  • μƒμ†μš© ν΄λž˜μŠ€λŠ” μž¬μ •μ˜ν•  수 μžˆλŠ” λ©”μ„œλ“œλ“€μ„ λ‚΄λΆ€μ μœΌλ‘œ μ–΄λ–»κ²Œ μ΄μš©ν•˜λŠ”μ§€(μžκΈ°μ‚¬μš©) λ¬Έμ„œλ‘œ 남겨야 함
  • 클래슀의 λ‚΄λΆ€ λ™μž‘ κ³Όμ • 쀑간에 끼어듀 수 μžˆλŠ” ν›…(hook)을 잘 μ„ λ³„ν•˜μ—¬ protected λ©”μ„œλ“œ ν˜•νƒœλ‘œ κ³΅κ°œν•΄μ•Ό ν•  μˆ˜λ„ 있음. ex) java.util.AbstractList의 removeRange λ©”μ„œλ“œ
  • μƒμ†μš© 클래슀λ₯Ό μ‹œν—˜ν•˜λŠ” 방법은 직접 ν•˜μœ„ 클래슀λ₯Ό λ§Œλ“€μ–΄ λ³΄λŠ” 것이 β€˜μœ μΌβ€™ν•¨
  • μƒμ†μš©μœΌλ‘œ μ„€κ³„ν•œ ν΄λž˜μŠ€λŠ” 배포 전에 λ°˜λ“œμ‹œ ν•˜μœ„ 클래슀λ₯Ό λ§Œλ“€μ–΄ 검증해야 함
  • μƒμ†μš© 클래슀의 μƒμ„±μžλŠ” μ§μ ‘μ μœΌλ‘œλ“  κ°„μ ‘μ μœΌλ‘œλ“  μž¬μ •μ˜ κ°€λŠ₯ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄μ„œλŠ” μ•ˆ 됨
  • cloneκ³Ό readObject λͺ¨λ‘ μ§μ ‘μ μœΌλ‘œλ“  κ°„μ ‘μ μœΌλ‘œλ“  μž¬μ •μ˜ κ°€λŠ₯ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄μ„œλŠ” μ•ˆ 됨

β†’ 클래슀λ₯Ό μƒμ†μš©μœΌλ‘œ μ„€κ³„ν•˜λ €λ©΄ μ—„μ²­λ‚œ λ…Έλ ₯이 λ“€κ³  κ·Έ ν΄λž˜μŠ€μ— μ•ˆκΈ°λŠ” μ œμ•½λ„ 상당함..


2. 상속 κΈˆμ§€

β†’ 클래슀λ₯Ό ν™•μž₯ν•΄μ•Ό ν•  λͺ…ν™•ν•œ μ΄μœ κ°€ μ—†λ‹€λ©΄ 상속을 κΈˆμ§€ν•˜μž

  • 방법1) 클래슀λ₯Ό final둜 μ„ μ–Έ
  • 방법2) λͺ¨λ“  μƒμ„±μžλ₯Ό privateμ΄λ‚˜ package-private으둜 μ„ μ–Έ ν›„ public 정적 νŒ©ν„°λ¦¬ 제곡


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

β€œμΌλ°˜μ μœΌλ‘œ 닀쀑 κ΅¬ν˜„μš© νƒ€μž…μœΌλ‘œ μΈν„°νŽ˜μ΄μŠ€κ°€ κ°€μž₯ 적합”

1. μΈν„°νŽ˜μ΄μŠ€μ™€ 좔상 클래슀

  • μžλ°”κ°€ μ œκ³΅ν•˜λŠ” 두 가지 닀쀑 κ΅¬ν˜„ λ©”μ»€λ‹ˆμ¦˜μ€ μΈν„°νŽ˜μ΄μŠ€μ™€ 좔상 클래슀.
  • μΈν„°νŽ˜μ΄μŠ€ vs 좔상 클래슀
닀쀑상속 κ°€λŠ₯ 여뢀계측 ꡬ쑰
좔상 ν΄λž˜μŠ€λΆˆκ°€μƒν•˜ 관계
μΈν„°νŽ˜μ΄μŠ€κ°€λŠ₯x

2. μΈν„°νŽ˜μ΄μŠ€μ˜ νŠΉμ§•

  • κΈ°μ‘΄ ν΄λž˜μŠ€μ—λ„ μ†μ‰½κ²Œ μƒˆλ‘œμš΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄λ„£μ„ 수 있음
  • μΈν„°νŽ˜μ΄μŠ€λŠ” 믹슀인(mixin) μ •μ˜μ— μ•ˆμ„±λ§žμΆ€
    • λŒ€μƒ νƒ€μž…μ˜ 주된 κΈ°λŠ₯에 선택적 κΈ°λŠ₯을 β€˜ν˜Όν•©(mixed in)’
    • 좔상 ν΄λž˜μŠ€λŠ” 닀쀑 상속이 λΆˆκ°€λŠ₯ν•˜λ―€λ‘œ 믹슀인 λΆˆκ°€.
  • μΈν„°νŽ˜μ΄μŠ€λ‘œλŠ” 계측ꡬ쑰가 μ—†λŠ” νƒ€μž… ν”„λ ˆμž„μ›Œν¬λ₯Ό λ§Œλ“€ 수 있음
    • μ•„λž˜ μ½”λ“œμ˜ ꡬ쑰λ₯Ό 클래슀둜 λ§Œλ“€λ €λ©΄ κ°€λŠ₯ν•œ μ‘°ν•© μ „λΆ€λ₯Ό 각각의 클래슀둜 μ •μ˜ν•œ κ³ λ„λΉ„λ§Œ 계측ꡬ쑰가 λ§Œλ“€μ–΄μ§
      • 속성이 n개라면 지원해야 ν•  μ‘°ν•©μ˜ μˆ˜λŠ” 2n2^n개
      • ν”νžˆ μ‘°ν•© 폭발(combinatorial explosion)이라 λΆ€λ₯΄λŠ” ν˜„μƒ.
public interface Singer {
		AudioClip sing(Song s);
}

public interface Songwriter {
		Song compose(int chartPosition);
}

public interface SingerSongwriter extends Singer, Songwriter {
		AudioClip strum();
		void actSensitive();
}
  • μΈν„°νŽ˜μ΄μŠ€λŠ” κΈ°λŠ₯을 ν–₯μƒμ‹œν‚€λŠ” μ•ˆμ „ν•˜κ³  κ°•λ ₯ν•œ μˆ˜λ‹¨
  • μΈν„°νŽ˜μ΄μŠ€μ˜ λ©”μ„œλ“œ 쀑 κ΅¬ν˜„ 방법이 λͺ…λ°±ν•œ 것이 μžˆλ‹€λ©΄, κ·Έ κ΅¬ν˜„μ„ λ””ν΄νŠΈ λ©”μ„œλ“œλ‘œ μ œκ³΅ν•  수 있음
    • λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•  λ•ŒλŠ” μƒμ†ν•˜λ €λŠ” μ‚¬λžŒμ„ μœ„ν•œ μ„€λͺ…을 @implSpec μžλ°”λ… νƒœκ·Έλ₯Ό λΆ™μ—¬ λ¬Έμ„œν™”ν•΄μ•Ό 함.

3. ν…œν”Œλ¦Ώ λ©”μ„œλ“œ νŒ¨ν„΄

  • μ •μ˜ : 상속을 톡해 슈퍼클래슀의 κΈ°λŠ₯을 ν™•μž₯ν•  λ•Œ μ‚¬μš©ν•˜λŠ” κ°€μž₯ λŒ€ν‘œμ μΈ 방법. λ³€ν•˜μ§€ μ•ŠλŠ” κΈ°λŠ₯은 μŠˆνΌν΄λž˜μŠ€μ— λ§Œλ“€μ–΄λ‘κ³  자주 λ³€κ²½λ˜λ©° ν™•μž₯ν•  κΈ°λŠ₯은 μ„œλΈŒν΄λž˜μŠ€μ—μ„œ λ§Œλ“€λ„λ‘ ν•œλ‹€.Β (ν† λΉ„μ˜ μŠ€ν”„λ§ 3.1)
  • μΈν„°νŽ˜μ΄μŠ€μ™€ 좔상 골격 κ΅¬ν˜„(skeletal implementation) 클래슀λ₯Ό ν•¨κ»˜ 제곡
    • 좔상 골격 κ΅¬ν˜„ ν΄λž˜μŠ€λŠ” μœ„ μ •μ˜μ—μ„œ μŠˆνΌν΄λž˜μŠ€μ— ν•΄λ‹Ή
    • 관둀상 AbstractInterface ν˜•μ‹μœΌλ‘œ 이름을 μ§€μŒ
      • ex) AbstractSet, AbstractList λ“±
  • λ‹¨μˆœνžˆ 골격 κ΅¬ν˜„μ„ ν™•μž₯ν•˜λŠ” κ²ƒλ§ŒμœΌλ‘œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” 데 ν•„μš”ν•œ 일이 λŒ€λΆ€λΆ„ μ™„λ£Œ
  • 골격 κ΅¬ν˜„ 클래슀 μ˜ˆμ‹œ
// 골격 κ΅¬ν˜„ 클래슀
public abstract class AbstractMapEntry<K,V> implements Map.Entry<K,V> {
    // λ³€κ²½ κ°€λŠ₯ν•œ μ—”νŠΈλ¦¬λŠ” 이 λ©”μ„œλ“œλ₯Ό λ°˜λ“œμ‹œ μž¬μ •μ˜ν•΄μ•Ό ν•œλ‹€.
    @Override public V setValue(V value) {
        throw new UnsupportedOperationException();
    }
    
    // Map.Entry.equals의 일반 κ·œμ•½μ„ κ΅¬ν˜„ν•œλ‹€.
    @Override public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof Map.Entry))
            return false;
        Map.Entry<?,?> e = (Map.Entry) o;
        return Objects.equals(e.getKey(),   getKey())
                && Objects.equals(e.getValue(), getValue());
    }

    // Map.Entry.hashCode의 일반 κ·œμ•½μ„ κ΅¬ν˜„ν•œλ‹€.
    @Override public int hashCode() {
        return Objects.hashCode(getKey())
                ^ Objects.hashCode(getValue());
    }

    @Override public String toString() {
        return getKey() + "=" + getValue();
    }
}


πŸ’‘ μΈν„°νŽ˜μ΄μŠ€λŠ” κ΅¬ν˜„ν•˜λŠ” μͺ½μ„ 생각해 μ„€κ³„ν•˜λΌ

β€œμ‹¬κ°ν•˜κ²Œ 잘λͺ»λœ μΈν„°νŽ˜μ΄μŠ€λŠ” 이λ₯Ό ν¬ν•¨ν•œ API에 μ–΄λ–€ μž¬μ•™μ„ λͺ°κ³  μ˜¬μ§€ μ•Œ 수 μ—†λ‹€.”

1. λ””ν΄νŠΈ λ©”μ„œλ“œ

  • μ„€λͺ… : λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•˜λ©΄, κ·Έ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν›„ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν•˜μ§€ μ•Šμ€ λͺ¨λ“  ν΄λž˜μŠ€μ—μ„œ λ””ν΄νŠΈ κ΅¬ν˜„μ΄ μ“°μž„
  • 생각할 수 μžˆλŠ” λͺ¨λ“  μƒν™©μ—μ„œ λΆˆλ³€μ‹μ„ ν•΄μΉ˜μ§€ μ•ŠλŠ” λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•˜κΈ°λž€ μ–΄λ €μš΄ 법
  • μƒˆλ‘œ μΆ”κ°€λœ λ””ν΄νŠΈ λ©”μ„œλ“œλŠ” (μ»΄νŒŒμΌμ— μ„±κ³΅ν•˜λ”λΌλ„) κΈ°μ‘΄ κ΅¬ν˜„μ²΄μ— λŸ°νƒ€μž„ 였λ₯˜λ₯Ό μΌμœΌν‚¬ 수 있음

β†’ κΈ°μ‘΄ μΈν„°νŽ˜μ΄μŠ€μ— λ””ν΄νŠΈ λ©”μ„œλ“œλ‘œ μƒˆ λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜λŠ” 일은 κΌ­ ν•„μš”ν•œ κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ ν”Όν•˜μž


2. 릴리슀

  • μƒˆλ‘œμš΄ μΈν„°νŽ˜μ΄μŠ€λΌλ©΄ 릴리슀 전에 λ°˜λ“œμ‹œ ν…ŒμŠ€νŠΈλ₯Ό 거쳐야 함.
    • 수 λ§Žμ€ κ°œλ°œμžκ°€ ν•΄λ‹Ή μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ‹€μ–‘ν•œ λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•  κ²ƒμ΄λ‹ˆ, μ΅œμ†Œ μ„œλ‘œ λ‹€λ₯Έ 3가지 λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•œ ν›„ ν…ŒμŠ€νŠΈ 해보아야 함.
    • 각 μΈν„°νŽ˜μ΄μŠ€μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ‹€μ–‘ν•œ μž‘μ—…μ— ν™œμš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈλ„ μ—¬λŸ¬ 개 λ§Œλ“€μ–΄λ΄μ•Ό 함
  • μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ¦΄λ¦¬μŠ€ν•œ 후라도 결함을 μˆ˜μ •ν•˜λŠ” 게 κ°€λŠ₯ν•˜λŠ” 게 κ°€λŠ₯ν•œ κ²½μš°λ„ μžˆκ² μ§€λ§Œ, μ ˆλŒ€ κ·Έ κ°€λŠ₯성에 κΈ°λŒ€μ„œλŠ” μ•ˆ 됨.


πŸ’‘ μΈν„°νŽ˜μ΄μŠ€λŠ” νƒ€μž…μ„ μ •μ˜ν•˜λŠ” μš©λ„λ‘œλ§Œ μ‚¬μš©ν•˜λΌ

β€œμΈν„°νŽ˜μ΄μŠ€λŠ” νƒ€μž… μ •μ˜ μš©λ„, μƒμˆ˜ μΈν„°νŽ˜μ΄μŠ€ μ•ˆν‹° νŒ¨ν„΄ 지양”

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

  • μΈν„°νŽ˜μ΄μŠ€λŠ” μžμ‹ μ„ κ΅¬ν˜„ν•œ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•  수 μžˆλŠ” νƒ€μž… 역할을 함.
  • ν΄λž˜μŠ€κ°€ μ–΄λ–€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œλ‹€λŠ” 것은 μžμ‹ μ˜ μΈν„°νŽ˜μ΄μŠ€λ‘œ 무엇을 ν•  수 μžˆλŠ”μ§€λ₯Ό ν΄λΌμ΄μ–ΈνŠΈμ— μ–˜κΈ°ν•΄μ£ΌλŠ” 것. 였직 μ΄μš©λ„λ‘œλ§Œ μ‚¬μš©ν•΄μ•Ό 함.

2. μƒμˆ˜ μΈν„°νŽ˜μ΄μŠ€ μ•ˆν‹° νŒ¨ν„΄

  • μƒμˆ˜ μΈν„°νŽ˜μ΄μŠ€ μ•ˆν‹° νŒ¨ν„΄μ€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 잘λͺ» ν™œμš©ν•œ 예
  • μƒμˆ˜ μΈν„°νŽ˜μ΄μŠ€ μ•ˆν‹° νŒ¨ν„΄ μ½”λ“œ (μ‚¬μš© κΈˆμ§€)
// μƒμˆ˜ μΈν„°νŽ˜μ΄μŠ€ μ•ˆν‹°νŒ¨ν„΄ - μ‚¬μš©κΈˆμ§€!
public interface PhysicalConstants {
    // μ•„λ³΄κ°€λ“œλ‘œ 수 (1/λͺ°)
    static final double AVOGADROS_NUMBER   = 6.022_140_857e23;

    // 볼츠만 μƒμˆ˜ (J/K)
    static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;

    // μ „μž μ§ˆλŸ‰ (kg)
    static final double ELECTRON_MASS      = 9.109_383_56e-31;
}
  • final이 μ•„λ‹Œ ν΄λž˜μŠ€κ°€ μƒμˆ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œλ‹€λ©΄ λͺ¨λ“  ν•˜μœ„ 클래슀의 이름곡간이 κ·Έ μΈν„°νŽ˜μ΄μŠ€κ°€ μ •μ˜ν•œ μƒμˆ˜λ“€λ‘œ μ˜€μ—Όλ˜μ–΄ 버림
  • ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œκ°€ λ‚΄λΆ€ κ΅¬ν˜„μ— ν•΄λ‹Ήν•˜λŠ” 이 μƒμˆ˜λ“€μ— μ’…μ†λ˜κ²Œ 함. κ·Έλž˜μ„œ λ‹€μŒ λ¦΄λ¦¬μŠ€μ—μ„œ 이 μƒμˆ˜λ“€μ„ λ”λŠ” 쓰지 μ•Šκ²Œ λ˜λ”λΌλ„ λ°”μ΄λ„ˆλ¦¬ ν˜Έν™˜μ„±μ„ μœ„ν•΄ μ—¬μ „νžˆ μƒμˆ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜κ³  μžˆμ–΄μ•Ό 함.

3. μ˜¬λ°”λ₯Έ μƒμˆ˜ 곡개 방법

  1. νŠΉμ • ν΄λž˜μŠ€λ‚˜ μΈν„°νŽ˜μ΄μŠ€μ™€ κ°•ν•˜κ²Œ μ—°κ΄€λœ μƒμˆ˜μΌ 경우 : κ·Έ ν΄λž˜μŠ€λ‚˜ μΈν„°νŽ˜μ΄μŠ€ μžμ²΄μ— μΆ”κ°€
    • ex) Integer의 MIN_VALUE μƒμˆ˜
  2. μ—΄κ±° νƒ€μž…μœΌλ‘œ λ‚˜νƒ€λ‚΄κΈ° μ ν•©ν•œ 경우 : μ—΄κ±° νƒ€μž…μœΌλ‘œ 곡개
  3. 1, 2κ°€ μ•„λ‹Œ 경우 : μΈμŠ€ν„΄μŠ€ν™”ν•  수 μ—†λŠ” μœ ν‹Έλ¦¬ν‹° ν΄λž˜μŠ€μ— λ‹΄μ•„μ„œ 곡개
// μƒμˆ˜ μœ ν‹Έλ¦¬ν‹° 클래슀 
public class PhysicalConstants {
  private PhysicalConstants() { }  // μΈμŠ€ν„΄μŠ€ν™” 방지

  // μ•„λ³΄κ°€λ“œλ‘œ 수 (1/λͺ°)
  public static final double AVOGADROS_NUMBER = 6.022_140_857e23;

  // 볼츠만 μƒμˆ˜ (J/K)
  public static final double BOLTZMANN_CONST  = 1.380_648_52e-23;

  // μ „μž μ§ˆλŸ‰ (kg)
  public static final double ELECTRON_MASS    = 9.109_383_56e-31;
}

// μƒμˆ˜ μ‚¬μš©μ‹œ
PhysicalConstants.AVOGADROS_NUMBER;


πŸ’‘ νƒœκ·Έ 달린 ν΄λž˜μŠ€λ³΄λ‹€λŠ” 클래슀 계측ꡬ쑰λ₯Ό ν™œμš©ν•˜λΌ

β€œνƒœκ·Έ 달린 ν΄λž˜μŠ€λŠ” 클래슀 계측ꡬ쑰λ₯Ό μ–΄μ„€ν”„κ²Œ 흉내낸 μ•„λ₯˜β€

1. νƒœκ·Έ 달린 클래슀

  • 두 가지 μ΄μƒμ˜ 의미λ₯Ό ν‘œν˜„ν•  수 있으며, 그쀑 ν˜„μž¬ ν‘œν˜„ν•˜λŠ” 의미λ₯Ό νƒœκ·Έ κ°’μœΌλ‘œ μ•Œλ €μ£ΌλŠ” 클래슀
  • νƒœκ·Έ 달린 클래슀 μ˜ˆμ‹œ μ½”λ“œ
// νƒœκ·Έ 달린 클래슀 - 클래슀 계측ꡬ쑰보닀 훨씬 λ‚˜μ˜λ‹€!
class Figure {
    enum Shape { RECTANGLE, CIRCLE };

    // νƒœκ·Έ ν•„λ“œ - ν˜„μž¬ λͺ¨μ–‘을 λ‚˜νƒ€λ‚Έλ‹€.
    final Shape shape;

    // λ‹€μŒ ν•„λ“œλ“€μ€ λͺ¨μ–‘이 μ‚¬κ°ν˜•(RECTANGLE)일 λ•Œλ§Œ 쓰인닀.
    double length;
    double width;

    // λ‹€μŒ ν•„λ“œλŠ” λͺ¨μ–‘이 원(CIRCLE)일 λ•Œλ§Œ 쓰인닀.
    double radius;

    // μ›μš© μƒμ„±μž
    Figure(double radius) {
        shape = Shape.CIRCLE;
        this.radius = radius;
    }

    // μ‚¬κ°ν˜•μš© μƒμ„±μž
    Figure(double length, double width) {
        shape = Shape.RECTANGLE;
        this.length = length;
        this.width = width;
    }

    double area() {
        switch(shape) {
            case RECTANGLE:
                return length * width;
            case CIRCLE:
                return Math.PI * (radius * radius);
            default:
                throw new AssertionError(shape);
        }
    }
}
  • νƒœκ·Έ 달린 클래슀의 문제점
    • μ—΄κ±° νƒ€μž… μ„ μ–Έ, νƒœκ·Έ ν•„λ“œ, switchλ¬Έ λ“± 쓸데 μ—†λŠ” μ½”λ“œκ°€ 많음
    • 가독성↓
    • λ‹€λ₯Έ 의미λ₯Ό μœ„ν•œ μ½”λ“œλ“€ λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬ μ‚¬μš©β†‘
    • μΈμŠ€ν„΄μŠ€ νƒ€μž…λ§ŒμœΌλ‘œλŠ” ν˜„μž¬ λ‚˜νƒ€λ‚΄λŠ” 의미λ₯Ό νŒŒμ•…ν•˜κΈ° 어렀움

2. μ„œλΈŒνƒ€μ΄ν•‘

β†’ νƒœκ·Έ 달린 ν΄λž˜μŠ€λŠ” κ³„μΈ΅κ΅¬μ‘°λ‘œ λ°”κΏ”μ„œ μ‚¬μš©ν•˜μž

  • 클래슀 κ³„μΈ΅κ΅¬μ‘°λŠ” νƒœκ·Έ 달린 클래슀의 단점을 λͺ¨λ‘ 날렀버림
  • νƒœκ·Έ 달린 클래슀λ₯Ό κ³„μΈ΅κ΅¬μ‘°λ‘œ λ³€ν™˜ν•˜λŠ” 방법
    1. κ³„μΈ΅κ΅¬μ‘°μ˜ 루트(root)κ°€ 될 좔상 클래슀 μ •μ˜
    2. νƒœκ·Έ 값에 따라 λ™μž‘μ΄ λ‹¬λΌμ§€λŠ” λ©”μ„œλ“œλ“€μ„ 루트 클래슀의 μΆ”μƒλ©”μ„œλ“œλ‘œ μ •μ˜
    3. νƒœκ·Έ 값에 상관없이 λ™μž‘μ΄ μΌμ •ν•œ λ©”μ„œλ“œλ“€μ„ 루트 ν΄λž˜μŠ€μ— 일반 λ©”μ„œλ“œλ‘œ μΆ”κ°€
    4. 루트 클래슀λ₯Ό ν™•μž₯ν•œ ꡬ체 클래슀λ₯Ό μ˜λ―Έλ³„λ‘œ ν•˜λ‚˜μ”© μ •μ˜
  • νƒœκ·Έ 달린 클래슀λ₯Ό κ³„μΈ΅κ΅¬μ‘°λ‘œ λ³€ν™˜ν•œ μ½”λ“œ μ˜ˆμ‹œ
// νƒœκ·Έ 달린 클래슀λ₯Ό 클래슀 κ³„μΈ΅κ΅¬μ‘°λ‘œ λ³€ν™˜
abstract class Figure {
    abstract double area();
}

class Rectangle extends Figure {
    final double length;
    final double width;

    Rectangle(double length, double width) {
        this.length = length;
        this.width  = width;
    }
    @Override double area() { return length * width; }
}

class Circle extends Figure {
    final double radius;

    Circle(double radius) { this.radius = radius; }

    @Override double area() { return Math.PI * (radius * radius); }
}


πŸ’‘ 멀버 ν΄λž˜μŠ€λŠ” λ˜λ„λ‘ static으둜 λ§Œλ“€λΌ

β€œλ„€ 가지 쀑첩 클래슀의 μ“°μž„ μ„€λͺ…”

1. 정적 멀버 클래슀

  • ν”νžˆ λ°”κΉ₯ ν΄λž˜μŠ€μ™€ ν•¨κ»˜ 쓰일 λ•Œλ§Œ μœ μš©ν•œ public λ„μš°λ―Έ 클래슀 μš©λ„λ‘œ μ‚¬μš©
  • ex) Calculator.Operation μ—΄κ±° νƒ€μž…
  • λ°”κΉ₯ μΈμŠ€ν„΄μŠ€μ™€ λ…λ¦½μ μœΌλ‘œ 쑴재.

2. 비정적 멀버 클래슀

  • μ–΄λŒ‘ν„°λ₯Ό μ •μ˜ν•  λ•Œ 자주 μ‚¬μš©. 즉, μ–΄λ–€ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό 감싸 마치 λ‹€λ₯Έ 클래슀의 μΈμŠ€ν„΄μŠ€μ²˜λŸΌ 보이게 ν•˜λŠ” 뷰둜 μ‚¬μš©.
  • ex) μ»¬λ ‰μ…˜ μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„λ“€μ˜ 반볡자(iterator)
public class MySet<E> extends AbstractSet<E> {
		... // μƒλž΅
		@Override public Iterator<E> iterator() {
				return new MyIterator();
		}

		private class MyIterator implements Iterator<E> {
				...
		}
}
  • λ°”κΉ₯ μΈμŠ€ν„΄μŠ€μ™€ μ•”λ¬΅μ μœΌλ‘œ μ—°κ²°. thisλ₯Ό μ‚¬μš©ν•΄ λ°”κΉ₯ μΈμŠ€ν„΄μŠ€ μ°Έμ‘° κ°€λŠ₯.
  • λ°”κΉ₯ μΈμŠ€ν„΄μŠ€ 없이 생성 λΆˆκ°€

3. 읡λͺ… 클래슀

  • 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•  λ•Œ 주둜 μ“°μž„
  • μ“°μ΄λŠ” μ‹œμ μ— μ„ μ–Έκ³Ό λ™μ‹œμ— μΈμŠ€ν„΄μŠ€ 생성
  • 비정적인 λ¬Έλ§₯μ—μ„œ μ‚¬μš©λ  λ•Œλ§Œ λ°”κΉ₯ 클래슀의 μΈμŠ€ν„΄μŠ€ μ°Έμ‘° κ°€λŠ₯.
  • 정적 λ¬Έλ§₯μ—μ„œλΌλ„ μƒμˆ˜ λ³€μˆ˜ μ΄μ™Έμ˜ 정적 λ©€λ²„λŠ” κ°€μ§ˆ 수 μ—†μŒ.
  • μ œμ•½μ΄ 많음
    • μ„ μ–Έν•œ μ§€μ μ—μ„œλ§Œ μΈμŠ€ν„΄μŠ€ 생성 κ°€λŠ₯
    • instanceof κ²€μ‚¬λ‚˜ 클래슀의 이름이 ν•„μš”ν•œ μž‘μ—… μˆ˜ν–‰ λΆˆκ°€
    • 읡λͺ… 클래슀λ₯Ό μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈλŠ” κ·Έ 읡λͺ… ν΄λž˜μŠ€κ°€ μƒμœ„ νƒ€μž…μ—μ„œ μƒμ†ν•œ 멀버 μ™Έμ—λŠ” 호좜 λΆˆκ°€
    • ν‘œν˜„μ‹ 쀑간에 λ“±μž₯ν•˜λ―€λ‘œ (10쀄 μ΄ν•˜λ‘œ) 짧지 μ•ŠμœΌλ©΄ 가독성↓

4. 지역 클래슀

  • λ„€ 가지 쀑첩 클래슀 쀑 κ°€μž₯ λ“œλ¬Όκ²Œ μ‚¬μš© 됨
  • μ§€μ—­λ³€μˆ˜λ₯Ό μ„ μ–Έν•  수 μžˆλŠ” 곳이면 μ‹€μ§ˆμ μœΌλ‘œ μ–΄λ””μ„œλ“  μ„ μ–Έν•  수 있고, μœ νš¨λ²”μœ„λ„ μ§€μ—­λ³€μˆ˜μ™€ κ°™μŒ
  • 비정적 λ¬Έλ§₯μ—μ„œ μ‚¬μš©λ  λ•Œλ§Œ λ°”κΉ₯ μΈμŠ€ν„΄μŠ€ μ°Έμ‘° κ°€λŠ₯.
  • 정적 λ©€λ²„λŠ” κ°€μ§ˆ 수 μ—†μŒ.
  • 가독성을 μœ„ν•΄ 짧게 μž‘μ„±ν•΄μ•Ό 함.


πŸ’‘ ν†±λ ˆλ²¨ ν΄λž˜μŠ€λŠ” ν•œ νŒŒμΌμ— ν•˜λ‚˜λ§Œ λ‹΄μœΌλΌ

β€œμ†ŒμŠ€ 파일 ν•˜λ‚˜μ—λŠ” λ°˜λ“œμ‹œ ν†±λ ˆλ²¨ 클래슀(ν˜Ήμ€ ν†±λ ˆλ²¨ μΈν„°νŽ˜μ΄μŠ€)λ₯Ό ν•˜λ‚˜λ§Œ λ‹΄μžβ€

1. 잘λͺ»λœ μ˜ˆμ‹œ

  • Utensil.java
// 두 ν΄λž˜μŠ€κ°€ ν•œ 파일(Utensil.java)에 μ •μ˜λ˜μ—ˆλ‹€. - 따라 ν•˜μ§€ 말 것!
class Utensil {
    static final String NAME = "pan";
}

class Dessert {
    static final String NAME = "cake";
}
  • Dessert.java
// 두 ν΄λž˜μŠ€κ°€ ν•œ 파일(Dessert.java)에 μ •μ˜λ˜μ—ˆλ‹€. - 따라 ν•˜μ§€ 말 것!
class Utensil {
    static final String NAME = "pot";
}

class Dessert {
    static final String NAME = "pie";
}
  • Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println(Utensil.NAME + Dessert.NAME);
    }
}

  1. javac Main.java Dessert.java 둜 컴파일 ν•  경우
    1. μ»΄νŒŒμΌλŸ¬λŠ” κ°€μž₯ λ¨Όμ € Main.javaλ₯Ό 컴파일
    2. main λ©”μ„œλ“œ μ•ˆμ—μ„œ Utensil μ°Έμ‘°λ₯Ό λ§Œλ‚˜λ©΄ Utensil.java νŒŒμΌμ„ μ‚΄νŽ΄ Utensilκ³Ό Dessertλ₯Ό λͺ¨λ‘ μ •μ˜
    3. 두 번째 λͺ…령쀄 인수둜 λ„˜μ–΄μ˜¨ Dessert.javaλ₯Ό μ²˜λ¦¬ν•˜λ € ν•  λ•Œ, 같은 클래슀의 μ •μ˜κ°€ μžˆμŒμ„ μ•Œκ²Œ 되고 컴파일 였λ₯˜λ₯Ό λ±‰μŒ(클래슀 쀑볡 μ •μ˜)
  2. javac Main.java λ˜λŠ” javac Main.Utensil.java 둜 컴파일 ν•  경우
    1. μ»΄νŒŒμΌλŸ¬λŠ” κ°€μž₯ λ¨Όμ € Main.javaλ₯Ό 컴파일
    2. main λ©”μ„œλ“œ μ•ˆμ—μ„œ Utensil μ°Έμ‘°λ₯Ό λ§Œλ‚˜λ©΄ Utensil.java νŒŒμΌμ„ μ‚΄νŽ΄ Utensilκ³Ό Dessertλ₯Ό λͺ¨λ‘ μ •μ˜
    3. 정상 μž‘λ™ : pancake 좜λ ₯
  3. javac Dessert.java Main.java 둜 컴파일 ν•  경우
    1. μ»΄νŒŒμΌλŸ¬λŠ” κ°€μž₯ λ¨Όμ € Dessert.java을 μ‚΄νŽ΄ Utensilκ³Ό Dessertλ₯Ό λͺ¨λ‘ μ •μ˜
    2. 두 번째 λͺ…령쀄 인수둜 λ„˜μ–΄μ˜¨ Main.java 컴파일
    3. 정상 μž‘λ™ : potpie 좜λ ₯

β†’ 2, 3을 보면 컴파일 μˆœμ„œμ— 따라 좜λ ₯κ²°κ³Όκ°€ 달라짐을 확인할 수 있음.


2. ν•΄κ²°μ±…

  • λ‹¨μˆœνžˆ ν†±λ ˆλ²¨ ν΄λž˜μŠ€λ“€(Utensilκ³Ό Dessert)을 μ„œλ‘œ λ‹€λ₯Έ μ†ŒμŠ€ 파일둜 λΆ„λ¦¬ν•˜λ©΄ 됨
  • ꡳ이 μ—¬λŸ¬ ν†±λ ˆλ²¨ 클래슀λ₯Ό ν•œ νŒŒμΌμ— λ‹΄κ³  μ‹Άλ‹€λ©΄ μ•„λž˜ 처럼 정적 멀버 클래슀λ₯Ό μ‚¬μš©ν•˜λŠ” 방법을 κ³ λ―Όν•΄λ³Ό 수 있음.
// ν†±λ ˆλ²¨ ν΄λž˜μŠ€λ“€μ„ 정적 멀버 클래슀둜 λ°”κΏ”λ³Έ λͺ¨μŠ΅
public class Test {
    public static void main(String[] args) {
        System.out.println(Utensil.NAME + Dessert.NAME);
    }

    private static class Utensil {
        static final String NAME = "pan";
    }

    private static class Dessert {
        static final String NAME = "cake";
    }
}
profile
https://dev-peter.online/

0개의 λŒ“κΈ€