Post

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

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

13.1 λ³€ν™”ν•˜λŠ” API

μžλ°” 8μ—μ„œλŠ” κΈ°λ³Έ κ΅¬ν˜„μ„ ν¬ν•¨ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•  수 μžˆλ‹€.

  1. 정적 λ©”μ„œλ“œ μ‚¬μš©
  2. λ””ν΄νŠΈ λ©”μ„œλ“œ μ‚¬μš©

결과적으둜 κΈ°μ‘΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” ν΄λž˜μŠ€λŠ” μžλ™μœΌλ‘œ μΈν„°νŽ˜μ΄μŠ€μ— μΆ”κ°€λœ μƒˆλ‘œμš΄ λ©”μ„œλ“œμ˜ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό 상속, 기쑴의 μ½”λ“œ κ΅¬ν˜„μ„ 바꾸도둝 κ°•μš”ν•˜μ§€ μ•ŠμœΌλ©΄μ„œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ³€κ²½ν•  수 μžˆλ‹€.

λ””ν΄νŠΈ λ©”μ„œλ“œκ°€ μ—†λ˜ μ‹œμ ˆμ—λŠ” μΈν„°νŽ˜μ΄μŠ€μ— λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜λ©΄μ„œ μ—¬λŸ¬ λ¬Έμ œκ°€ λ°œμƒν–ˆλ‹€.

μƒˆλ‘œ μΆ”κ°€λœ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜λ„λ‘ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” κΈ°μ‘΄ 클래슀λ₯Ό κ³ μ³μ•Όν•˜κΈ° λ•Œλ¬Έ

13.1.1 API 버전 1

1
2
3
4
5
6
7
public interface Resizable extends Drawable {
	int getWidth();
	int getHeight();
	void setWidth(int width);
	void setHeight(int height);
	void setAbsoluteSize(int width, int height);
}

μ‚¬μš©μž κ΅¬ν˜„

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Ellipse implements Resizable {
	...
}

public class Game {
	public static void main(String ...args) {
		List<Resizable> resizableShapes = Arrays.asList(new Square(), new Rectangle(), new Ellipse());
		Utils.paint(resizableShapes);
	}
}

public class Utils {
	public static void paint(List<Resizable> l) {
		l.forEach(r -> {
			r.setAbsoluteSize(42, 42);
			r.draw();
		});
	}
}

13.1.2 API 버전2

Resizable 을 κ΅¬ν˜„ν•˜λŠ” Square, Rentangle κ΅¬ν˜„μ„ κ°œμ„ ν•΄λ‹¬λΌλŠ” μš”μ²­μœΌλ‘œ 버전2λ₯Ό μ œμž‘

1
2
3
4
5
6
7
8
public interface Resizable extends Drawable {
	int getWidth();
	int getHeight();
	void setWidth(int width);
	void setHeight(int height);
	void setAbsoluteSize(int width, int height);
	**void setRelativeSize(int wFactor, int hFactor);**
}

μ‚¬μš©μžκ°€ κ²ͺλŠ” 문제

라이브러리 μ‚¬μš©μžκ°€ 직접 κ΅¬ν˜„ν•œ Ellipse λŠ” μƒˆλ‘œμš΄ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•ŠλŠ”λ‹€.

μΈν„°νŽ˜μ΄μŠ€μ— μƒˆλ‘œμš΄ λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜λ©΄ λ°”μ΄λ„ˆλ¦¬ ν˜Έν™˜μ„±μ€ μœ μ§€λœλ‹€.

ν•˜μ§€λ§Œ 이후에 μƒˆλ‘œμš΄ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ λŸ°νƒ€μž„ μ—λŸ¬κ°€ λ°œμƒν•˜κ²Œ 될 것이닀.

λ˜ν•œ 전체 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μž¬λΉŒλ“œν• λ•Œ 컴파일 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

  • λ°”μ΄λ„ˆλ¦¬ ν˜Έν™˜μ„± : μ—λŸ¬μ—†μ΄ κΈ°μ‘΄ λ°”μ΄λ„ˆλ¦¬κ°€ 싀행될 수 μžˆλŠ” 상황 (ν˜ΈμΆœν•˜μ§€ μ•ŠλŠ” ν•œ)
  • μ†ŒμŠ€ ν˜Έν™˜μ„± : μ½”λ“œλ₯Ό 고쳐도 κΈ°μ‘΄ ν”„λ‘œκ·Έλž¨μ„ μ„±κ³΅μ μœΌλ‘œ μž¬μ»΄νŒŒμΌν•  수 있음
  • λ™μž‘ ν˜Έν™˜μ„± : μ½”λ“œλ₯Ό λ°”κΎΌ λ‹€μŒμ—λ„ 같은 μž…λ ₯값이 주어지면 같은 λ™μž‘μ„ μˆ˜ν–‰

13.2 λ””ν΄νŠΈ λ©”μ„œλ“œλž€ 무엇인가?

μžμ‹ μ„ κ΅¬ν˜„ν•˜λŠ” ν΄λž˜μŠ€μ—μ„œ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šμ„ 수 μžˆλŠ” μƒˆλ‘œμš΄ λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό 제곡

1
2
3
4
5
6
public interface Sized {
	int size();
	default boolean isEmptry() {
		return size() == 0;
	}
}

이제 Sized μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” λͺ¨λ“  ν΄λž˜μŠ€λŠ” isEmpty 의 κ΅¬ν˜„λ„ μƒμ†λ°›λŠ”λ‹€.

μžλ°” 8 API μ—μ„œλŠ” λ””ν΄νŠΈ λ©”μ„œλ“œκ°€ μƒλ‹Ήνžˆ 많이 ν™œμš©λ˜μ—ˆμ„ κ²ƒμž„μ„ μΆ”μΈ‘ν•  수 μžˆλ‹€.

  • Collection β†’ stream
  • List β†’ sort
  • ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ (λ””ν΄νŠΈ λ©”μ„œλ“œλŠ” 좔상 λ©”μ„œλ“œκ°€ μ•„λ‹˜)

좔상 ν΄λž˜μŠ€μ™€ μžλ°” 8의 μΈν„°νŽ˜μ΄μŠ€ 차이

  • 상속 : 좔상 ν΄λž˜μŠ€λŠ” 1개만 상속, μΈν„°νŽ˜μ΄μŠ€λŠ” μ—¬λŸ¬ 개 κ΅¬ν˜„ κ°€λŠ₯
  • λ³€μˆ˜ : 좔상 ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λ‘œ 곡톡 μƒνƒœλ₯Ό κ°€μ§ˆ 수있음, μΈν„°νŽ˜μ΄μŠ€λŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜κ°€ μ—†λ‹€

13.3 λ””ν΄νŠΈ λ©”μ„œλ“œ ν™œμš© νŒ¨ν„΄

13.3.1 μ„ νƒν˜• λ©”μ„œλ“œ

μžλ°” 8 이전에 Iterator λŠ” remove κΈ°λŠ₯을 잘 μ‚¬μš©ν•˜μ§€ μ•Šμ•„ 이 κΈ°λŠ₯을 λ¬΄μ‹œν–ˆκ³ , λ§Žμ€ Iterator λ₯Ό κ΅¬ν˜„ν•˜λŠ” ν΄λž˜μŠ€μ—μ„œ 빈 κ΅¬ν˜„μ„ μ œκ³΅ν–ˆλ‹€.

반면 λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜λ©΄ 빈 κ΅¬ν˜„μ„ μ œκ³΅ν•˜μ§€ μ•Šμ•„ λΆˆν•„μš”ν•œ μ½”λ“œλ₯Ό 쀄일 수 μžˆλ‹€.

1
2
3
4
5
6
7
interface Iterator<T> {
	boolean hasNext();
	T next();
	default void remove() {
		throw new UnsupportedOperationException();
	}
}

13.3.2 λ™μž‘ 닀쀑 상속

μžλ°”μ—μ„œ ν΄λž˜μŠ€λŠ” 1개의 λ‹€λ₯Έ 클래슀만 상속받을 수 μžˆμ§€λ§Œ

μΈν„°νŽ˜μ΄μŠ€λŠ” μ—¬λŸ¬ 개λ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€.

1
2
public class ArrayList<E> extends AbstractList<E>
	implements List<E>, RandomAccess, Cloneable, Serializable {}

닀쀑 상속 ν˜•μ‹

ArrayList λŠ” 결과적으둜 AbstractList, List, RandomAccess, Cloneable, Serializable, Iterable, Collection 의 μ„œλΈŒ ν˜•μ‹μ΄ λ˜μ–΄ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³ λ„ 닀쀑 상속을 ν™œμš©ν•  수 μžˆλ‹€.

κΈ°λŠ₯이 μ€‘λ³΅λ˜μ§€ μ•ŠλŠ” μ΅œμ†Œμ˜ μΈν„°νŽ˜μ΄μŠ€

1
2
3
4
5
public interface Rotatable {}

public interface Movable {}

public interface Resizable {}

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

이듀 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‘°ν•©ν•΄ λ‹€μ–‘ν•œ 클래슀λ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€.

1
2
3
public class Monster implements Rotatable, Moveable, Resizable {}

public class Sun implements Moveable, Rotatable {}

13.4 해석 κ·œμΉ™

μžλ°” 8에 λ””ν΄νŠΈ λ©”μ„œλ“œκ°€ μΆ”κ°€λ˜λ©΄μ„œ 같은 μ‹œκ·Έλ‹ˆμ²˜λ₯Ό κ°–λŠ” λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μƒμ†λ°›λŠ” 상황이 생길 수 μžˆλ‹€.

13.4.1 μ•Œμ•„μ•Ό ν•  μ„Έ 가지 ν•΄κ²° κ·œμΉ™

  1. ν΄λž˜μŠ€λ‚˜ μŠˆνΌν΄λž˜μŠ€μ—μ„œ μ •μ˜ν•œ λ©”μ„œλ“œκ°€ λ””ν΄νŠΈ λ©”μ„œλ“œλ³΄λ‹€ μš°μ„ 
  2. κ·Έ 외에 상속관계λ₯Ό κ°–λŠ” μΈν„°νŽ˜μ΄μŠ€μ—μ„œλŠ” μ„œλΈŒ μΈν„°νŽ˜μ΄μŠ€κ°€ μš°μ„ 
  3. κ·ΈλŸΌμ—λ„ 정해지지 μ•ŠλŠ”λ‹€λ©΄ λͺ…μ‹œμ μœΌλ‘œ μ˜€λ²„λΌμ΄λ“œ ν•΄μ•Όν•œλ‹€.

13.4.2 λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•˜λŠ” μ„œλΈŒμΈν„°νŽ˜μ΄μŠ€κ°€ 이긴닀

1
2
3
4
5
6
7
public class D implements A {}

public class C extends D implements B, A {
	public static void main(String ...args) {
		new C().hello();
	}
}

13.4.3 좩돌그리고 λͺ…μ‹œμ μΈ ν•΄κ²°

λ‹€μŒμ€ μΈν„°νŽ˜μ΄μŠ€κ°„ 상속관계가 μ—†μ–΄ hello λ©”μ„œλ“œλ₯Ό ꡬ별할 기쀀이 μ—†κ³ , μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

1
2
3
4
5
6
7
8
9
public interface A {
	default void hello() {}
}

public interface B {
	default void hello() {}
}

public class C implements B, A {}

좩돌 ν•΄κ²°

ν΄λž˜μŠ€μ™€ λ©”μ„œλ“œ κ΄€κ³„λ‘œ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό 선택할 수 μ—†λ‹€λ©΄ λͺ…μ‹œμ μœΌλ‘œ 선택해주어야 ν•œλ‹€.

μžλ°” 8μ—μ„œλŠ” 슈퍼 μΈν„°νŽ˜μ΄μŠ€μ˜ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλŠ” 문법을 μ œκ³΅ν•œλ‹€.

1
2
3
4
5
public class C implements B, A {
	void hello() {
		B.super.hello(); // λͺ…μ‹œμ μœΌλ‘œ B의 λ©”μ„œλ“œλ₯Ό 선택
	}
}

13.4.4 닀이아λͺ¬λ“œ 문제

1
2
3
4
5
6
7
8
9
10
11
12
public interface A {
	default void hello() {}
}

public interface B extends A {}
public interface C extends A {}

public class D implements B, C {
	public static void main(String ..args) {
		new D().hello();
	}
}

μ΄λŠ” A만 λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜κ³  μžˆμ–΄ A의 λ©”μ„œλ“œκ°€ ν˜ΈμΆœλœλ‹€.

λ§Œμ•½ B에도 같은 μ‹œκ·Έλ‹ˆμ²˜μ˜ λ””ν΄νŠΈ λ©”μ„œλ“œκ°€ μžˆλ‹€λ©΄?

이 λ•ŒλŠ” 좩돌이 λ°œμƒν•˜κΈ° λ•Œλ¬Έμ— λͺ…μ‹œμ  호좜이 ν•„μš”ν•˜λ‹€

λ§Œμ•½ C에 λ””ν΄νŠΈ λ©”μ„œλ“œκ°€ μ•„λ‹Œ 좔상 λ©”μ„œλ“œ hello λ₯Ό μΆ”κ°€ν•˜λ©΄?

1
2
3
public interface C extends A {
	void hello();
}

CλŠ” Aλ₯Ό 상속받기 λŒ€λ¬Έμ— C의 λ©”μ„œλ“œκ°€ ν˜ΈμΆœλœλ‹€

즉 컴파일 μ—λŸ¬κ°€ λ°œμƒν•˜λ©°, 클래슀 DλŠ” μ–΄λ–€ hello λ₯Ό μ‚¬μš©ν• μ§€ λͺ…μ‹œμ μœΌλ‘œ μ„€μ •ν•΄μ•Ό ν•œλ‹€.

This post is licensed under CC BY 4.0 by the author.