Post

๐Ÿน chap13. ๋””ํดํŠธ ๋ฉ”์„œ๋“œ

์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ณ€๊ฒฝ(์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€ ๋“ฑ)ํ•˜๊ณ ์ž ํ•  ๋•Œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†ํ•œ ๋ชจ๋“  ํด๋ž˜์Šค๋ฅผ ๊ณ ์ณ์•ผ ํ•œ๋‹ค๋ฉด ๋งค์šฐ ๋‹นํ™ฉ์Šค๋Ÿฌ์šธ ๊ฒƒ์ด๋‹ค.

์ž๋ฐ” 8์—์„œ๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ์ž๋ฐ” 8์—์„œ๋Š” ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ํฌํ•จํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค.

  1. ์ธํ„ฐํŽ˜์ด์Šค ๋‚ด๋ถ€์— ์ •์  ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ
  2. ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ๋””ํดํŠธ ๋ฉ”์„œ๋“œ ๊ธฐ๋Šฅ ์‚ฌ์šฉ

๋ฉ”์„œ๋“œ ๊ตฌํ˜„์„ ํฌํ•จํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ๊ธฐ์กด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๋Š” ์ž๋™์œผ๋กœ ์ธํ„ฐํŽ˜์ด์Šค์— ์ถ”๊ฐ€๋œ ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ์˜ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›๊ฒŒ ๋œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธฐ์กด์˜ ์ฝ”๋“œ ๊ตฌํ˜„์„ ๋ฐ”๊พธ๋„๋ก ๊ฐ•์š”ํ•˜์ง€ ์•Š์œผ๋ฉด์„œ๋„ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋‘๊ฐ€์ง€ ์˜ˆ๋กœ List ์ธํ„ฐํŽ˜์ด์Šค์˜ sort์™€ Collection ์ธํ„ฐํŽ˜์ด์Šค์˜ stream ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค.

List ์ธํ„ฐํŽ˜์ด์Šค์˜ sort ๋ฉ”์„œ๋“œ๋Š” ์ž๋ฐ” 8์—์„œ ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๋ฉ”์„œ๋“œ๋‹ค. ๋‹ค์Œ์€ sort์˜ ๊ตฌํ˜„ ์ฝ”๋“œ๋‹ค.

1
2
3
default void sort(Comparator<? super E> c) {
    Collections.sort(this, c);
}

๋ฐ˜ํ™˜ ํ˜•์‹ void ์•ž์— default๋ผ๋Š” ์ƒˆ๋กœ์šด ํ‚ค์›Œ๋“œ๊ฐ€ ๋“ฑ์žฅํ–ˆ๋‹ค.

default ํ‚ค์›Œ๋“œ๋Š” ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ์ž„์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ์—ฌ๊ธฐ์„œ sort ๋ฉ”์„œ๋“œ๋Š” Collections.sort ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด ๋ฉ”์„œ๋“œ ๋•๋ถ„์— ๋ฆฌ์ŠคํŠธ์—์„œ ์ง์ ‘ sort๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

1
2
List<Integer> numbers = Arrays.asList(3, 5, 1, 2, 6);
numbers.sort(Comparator.naturalOrder()); //sort๋Š” List ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋‹ค

naturalOrder โ†’ ์ž์—ฐ์ˆœ์„œ(ํ‘œ์ค€ ์•ŒํŒŒ๋ฒณ ์ˆœ์„œ)๋กœ ์š”์†Œ๋ฅผ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ๋„๋ก Comparator ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” Comparator ์ธํ„ฐํŽ˜์ด์Šค์— ์ถ”๊ฐ€๋œ ์ƒˆ๋กœ์šด ์ •์  ๋ฉ”์„œ๋“œ๋‹ค.

๋‹ค์Œ์€ Collection์˜ stream ๋ฉ”์„œ๋“œ ์ •์˜ ์ฝ”๋“œ๋‹ค.

1
2
3
default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

stream ๋ฉ”์„œ๋“œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ StreamSupport.stream์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. stream ๋ฉ”์„œ๋“œ์˜ ๋‚ด๋ถ€์—์„œ๋Š” Collection ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋‹ค๋ฅธ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ spliterator๋„ ํ˜ธ์ถœํ•œ๋‹ค.

๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋Š” ์ฃผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค๊ณ„์ž๋“ค์ด ์‚ฌ์šฉํ•œ๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ์ž๋ฐ” API์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๋ฉฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค์— ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์—ฌ๋Ÿฌ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์—ˆ๋‹ค.

โ†’ ์ธํ„ฐํŽ˜์ด์Šค์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ธฐ์กด ํด๋ž˜์Šค๋ฅผ ๊ณ ์ณ์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ณธ์ธ์ด ์ง์ ‘ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ์–ด๋ ต์ง€ ์•Š๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋Œ€์ค‘์— ๊ณต๊ฐœํ–ˆ์„ ๋•Œ๋Š” ์ƒํ™ฉ์ด ๋‹ค๋ฅด๋‹ค.

๊ทธ๋ž˜์„œ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๊ฐ€ ํƒ„์ƒํ•˜์˜€๋‹ค.

๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ๊ทธ๋Œ€๋กœ ์ƒ์†ํ•˜๋ฏ€๋กœ ์ธํ„ฐํŽ˜์ด์Šค์— ์ž์œ ๋กญ๊ฒŒ ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์ค‘ ์ƒ์†์ด๋ผ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•˜๋ฉด์„œ ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์„ฑ์—๋„ ๋„์›€์„ ์ค€๋‹ค(์ด์ œ ํด๋ž˜์Šค๋Š” ์—ฌ๋Ÿฌ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค)

13.1 ๋ณ€ํ™”ํ•˜๋Š” API

ex) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค๊ณ„

  • ๋ชจ์–‘์˜ ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ setHeight, setWeight, getHeight, getWidth, setAbsoluteSize ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๋Š” Resizable ์ธํ„ฐํŽ˜์ด์Šค
  • Rectangle์ด๋‚˜ Square์ฒ˜๋Ÿผ Resizable์„ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค ์ œ๊ณต
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ธ๊ธฐ๋ฅผ ์–ป์œผ๋ฉฐ ์ผ๋ถ€ ์‚ฌ์šฉ์ž๋Š” ์ง์ ‘ Resizable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” Ellipse๋ผ๋Š” ํด๋ž˜์Šค ๊ตฌํ˜„

API๋ฅผ ๋ฆด๋ฆฌ์ฆˆ ํ•œ ํ›„ Resizable์— ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์ด ๋ถ€์กฑํ•˜๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Resizable ์ธํ„ฐํŽ˜์ด์Šค์— ํฌ๊ธฐ ์กฐ์ ˆ ์ธ์ˆ˜๋กœ ๋ชจ์–‘์˜ ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋Š” setRelativeSize๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋ž˜์„œ Resizable์— setRelativeSize๋ฅผ ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ์— Square๊ณผ Rectangle ๊ตฌํ˜„๋„ ๊ณ ์ณค๋‹ค.

์ด๋ ‡๊ฒŒ ๋˜๋ฉด Resizable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ์‚ฌ์šฉ์ž๋Š” ์–ด๋–ป๊ฒŒ ๋˜๋Š” ๊ฑธ๊นŒ?

์•ˆํƒ€๊น๊ฒŒ๋„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋งŒ๋“  ํด๋ž˜์Šค๋Š” ์šฐ๋ฆฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜๋Š” ์—†๋‹ค.

์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค๊ณ„์ž๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ฐ”๊พธ๊ณ  ์‹ถ์„ ๋•Œ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

13.1.1 API ๋ฒ„์ „ 1

Resizable ์ธํ„ฐํŽ˜์ด์Šค ์ดˆ๊ธฐ ๋ฒ„์ „์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ํฌํ•จํ•œ๋‹ค.

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);
}

์‚ฌ์šฉ์ž ๊ตฌํ˜„

์šฐ๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฆ๊ฒจ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž ์ค‘ ํ•œ ๋ช…์€ ์ง์ ‘ Resizable์„ ๊ตฌํ˜„ํ•˜๋Š” Ellipse ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

1
2
3
public class Ellipse implements Resizable {
    ...
}

์ด ์‚ฌ์šฉ์ž๋Š” ๋‹ค์–‘ํ•œ Resizable ๋ชจ์–‘(์ž์‹ ์ด ๋งŒ๋“  Ellipse๋ฅผ ํฌํ•จํ•˜์—ฌ)์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒŒ์ž„์„ ๋งŒ๋“ค์—ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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); //๊ฐ ๋ชจ์–‘์— setAbsoluteSize ํ˜ธ์ถœ
            r.draw();
        });
    }
}

13.1.2 API ๋ฒ„์ „ 2

๋ช‡ ๊ฐœ์›”์ด ์ง€๋‚˜์ž Resizable์„ ๊ตฌํ˜„ํ•˜๋Š” Square์™€ Rectangle ๊ตฌํ˜„์„ ๊ฐœ์„ ํ•ด๋‹ฌ๋ผ๋Š” ๋งŽ์€ ์š”์ฒญ์„ ๋ฐ›์•˜๋‹ค. ๊ทธ๋ž˜์„œ ๋‹ค์Œ์ฒ˜๋Ÿผ API ๋ฒ„์ „ 2๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
public interface Resizable {
    int getWidth();
    int getHeight();
    void setWidth(int width);
    void setHeight(int height);
    void setAbsoluteSize(int width, int height);
    // API ๋ฒ„์ „2์— ์ถ”๊ฐ€๋œ ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ
    void setRelativeSize(int wFactor, int hFactor);
}

์‚ฌ์šฉ์ž๊ฐ€ ๊ฒช๋Š” ๋ฌธ์ œ

Resizable์„ ๊ณ ์น˜๋ฉด ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

  1. Resizable์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ํด๋ž˜์Šค๋Š” setRelativeSize ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. (ํ•˜์ง€๋งŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๊ตฌํ˜„ํ•œ Ellipse๋Š” serRelativeSize ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๋Š”๋‹ค.)

    โ†’ ์ธํ„ฐํŽ˜์ด์Šค์— ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฐ”์ด๋„ˆ๋ฆฌ ํ˜ธํ™˜์„ฑ์€ ์œ ์ง€๋œ๋‹ค.

    (๋ฐ”์ด๋„ˆ๋ฆฌ ํ˜ธํ™˜์„ฑ: ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€๋งŒ ์•Š์œผ๋ฉด ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์ด ์—†์ด๋„ ๊ธฐ์กด ํด๋ž˜์Šค ํŒŒ์ผ ๊ตฌํ˜„์ด ์ž˜ ๋™์ž‘ํ•œ๋‹ค.)

    ํ•˜์ง€๋งŒ ์–ธ์  ๊ฐ€ ๋ˆ„๊ตฐ๊ฐ€๋Š” Resizable์„ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” Utils.paint์—์„œ setRelativeSize๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ Ellipse ๊ฐ์ฒด๊ฐ€ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋˜๋ฉด Ellipse๋Š” setRelativeSize ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๋Ÿฐํƒ€์ž„์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค.

    1
    2
    
     Exception in thread "main" java.lang.AbstractMethodError: lambdasinaction.chap9.
     Ellipse.setRelativeSize(II)V
    
  2. ์‚ฌ์šฉ์ž๊ฐ€ Ellipse๋ฅผ ํฌํ•จํ•˜๋Š” ์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์žฌ๋นŒ๋“œํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

    1
    2
    
     lambdasinaction/chap9/Ellipse.java:6: error: Ellipse is not abstract and does not
     override abstract method setRelativeSize(int, int) in Resizable
    

    ๊ณต๊ฐœ๋œ API๋ฅผ ๊ณ ์น˜๋ฉด ๊ธฐ์กด ๋ฒ„์ „๊ณผ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋Ÿฐ ์ด์œ  ๋•Œ๋ฌธ์— ๊ณต์‹ ์ž๋ฐ” ์ปฌ๋ ‰์…˜ API ๊ฐ™์€ ๊ธฐ์กด์˜ API๋Š” ๊ณ ์น˜๊ธฐ ์–ด๋ ต๋‹ค. ๋ฌผ๋ก  API๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋Œ€์•ˆ์ด ์žˆ์ง€๋งŒ ์™„๋ฒฝํ•œ ํ•ด๊ฒฐ์ฑ…์€ ๋  ์ˆ˜ ์—†๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด ์ž์‹ ๋งŒ์˜ API๋ฅผ ๋ณ„๋„๋กœ ๋งŒ๋“  ๋‹ค์Œ ์˜ˆ์ „ ๋ฒ„์ „๊ณผ ์ƒˆ๋กœ์šด ๋ฒ„์ „์„ ์ง์ ‘ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค. โ†’ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๋กœ ๋ถˆํŽธํ•œ ์ 

    (1) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ ๋ณต์žก

    (2) ์‚ฌ์šฉ์ž๋Š” ๊ฐ™์€ ์ฝ”๋“œ์— ์˜ˆ์ „ ๋ฒ„์ „๊ณผ ์ƒˆ๋กœ์šด ๋ฒ„์ „ ๋‘ ๊ฐ€์ง€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•ด์•ผ ํ•จ

    ๊ฒฐ๊ตญ ํ”„๋กœ์ ํŠธ์—์„œ ๋กœ๋”ฉํ•ด์•ผ ํ•  ํด๋ž˜์Šค ํŒŒ์ผ์ด ๋งŽ์•„์ง€๋ฉด์„œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๊ณผ ๋กœ๋”ฉ ์‹œ๊ฐ„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋กœ ์ด ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ API๋ฅผ ๋ฐ”๊พธ๋ฉด ์ƒˆ๋กญ๊ฒŒ ๋ฐ”๋€ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์ž๋™์œผ๋กœ ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜๋ฏ€๋กœ ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๊ณ ์น˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

13.2 ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

์ž๋ฐ” 8์—์„œ๋Š” ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ API๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋„๋ก ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ธ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ด์ œ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ž์‹ ์„ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์€ ๋ฉ”์„œ๋“œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค ์ž์ฒด์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•œ๋‹ค.(๊ทธ๋ž˜์„œ ๊ตฌํ˜„์ด ํ•„์ˆ˜๊ฐ€ ์•„๋‹˜)

๋””ํดํŠธ ๋ฉ”์„œ๋“œ

  • default๋ผ๋Š” ํ‚ค์›Œ๋“œ๋กœ ์‹œ์ž‘
  • ๋‹ค๋ฅธ ํด๋ž˜์Šค์— ์„ ์–ธ๋œ ๋ฉ”์„œ๋“œ์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ ๋ฐ”๋”” ํฌํ•จ

ex) ์ปฌ๋ ‰์…˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— Sized ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜

1
2
3
4
5
6
public interface Sized {
    int size();
    default boolean isEmpty() { // ๋””ํดํŠธ ๋ฉ”์„œ๋“œ
        return size() == 0;
    }
}

์ด์ œ Sized ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ํด๋ž˜์Šค๋Š” isEmpty์˜ ๊ตฌํ˜„๋„ ์ƒ์†๋ฐ›๋Š”๋‹ค. ์ฆ‰, ์ธํ„ฐํŽ˜์ด์Šค์— ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์†Œ์Šค ํ˜ธํ™˜์„ฑ์ด ์œ ์ง€๋œ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด setRelativeSize์˜ ๋””ํดํŠธ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜๋ฉด ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๋ฉฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ณ ์น  ์ˆ˜ ์žˆ๋‹ค.

1
2
default void setRelativeSize(int wFactor, int hFactor) {
    setAbsoluteSize(getWidth() / wFactor, getHeight() / hFactor);
  • ์ถ”์ƒ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ฐจ์ด
    1. ํด๋ž˜์Šค๋Š” ํ•˜๋‚˜์˜ ์ถ”์ƒ ํด๋ž˜์Šค๋งŒ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์—ฌ๋Ÿฌ ๊ฐœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
    2. ์ถ”์ƒ ํด๋ž˜์Šค๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜(ํ•„๋“œ)๋กœ ๊ณตํ†ต ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค.
  • Quiz. removeIf

    ์—ฌ๋Ÿฌ๋ถ„์ด ์ž๋ฐ” ์–ธ์–ด์™€ API์˜ ๋‹ฌ์ธ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜์ž. ์–ด๋Š ๋‚  ๋‹ค์ˆ˜์˜ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ArrayList.TreeSet, LinkedList ๋ฐ ๋‹ค๋ฅธ ๋ชจ๋“  ์ปฌ๋ ‰์…˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” removeIf ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด๋‹ฌ๋ผ๋Š” ์š”์ฒญ์„ ๋ฐ›์•˜๋‹ค. removeIf ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ํ”„๋ ˆ๋””์ผ€์ดํŠธ์™€ ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ปฌ๋ ‰์…˜์—์„œ ์ œ๊ฑฐํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ–‰ํ•œ๋‹ค. ์ƒˆ๋กœ์šด removeIf๋ฅผ ๊ธฐ์กด ์ปฌ๋ ‰์…˜ API์— ๊ฐ€์žฅ ์ ์ ˆํ•˜๊ฒŒ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ผ๊นŒ?

    • ์ •๋‹ต

      ์šฐ์„  ๋ฐ˜๋Œ€๋กœ ์ปฌ๋ ‰์…˜ API๋ฅผ ๊ณ ์น˜๋Š” ๊ฐ€์žฅ ์ข‹์ง€ ์•Š์€ ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ผ๊นŒ? ์ปฌ๋ ‰์…˜ API์˜ ๋ชจ๋“  ๊ตฌํ˜„ ํด๋ž˜์Šค์— removeIf๋ฅผ ๋ณต์‚ฌ&๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

      ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ์—†์„๊นŒ? ๋ชจ๋“  ์ปฌ๋ ‰์…˜ ํด๋ž˜์Šค๋Š” java.util.Collection ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด Collection ์ธํ„ฐํŽ˜์ด์Šค์— ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์„๊นŒ? ์ง€๊ธˆ๊นŒ์ง€ ํ™•์ธํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ธํ„ฐํŽ˜์ด์Šค์— ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ์†Œ์Šค ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด Collection์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ํด๋ž˜์Šค(๋ฌผ๋ก  ์ปฌ๋ ‰์…˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํด๋ž˜์Šค๋ฟ ์•„๋‹ˆ๋ผ Collection ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•œ ์‚ฌ์šฉ์ž ํด๋ž˜์Šค๋„ ํฌํ•จ)๋Š” ์ž๋™์œผ๋กœ removeIf๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
        default boolean removeIf(Predicate<? super E> filter) {
            boolean removed = false;
            Iterator<E> each = iterator();
            while(each.hasNext()) {
                if(filter.test(each.next())) {
                    each.remove();
                    removed = true;
                }
            }
            return removed;
        }
      

13.3 ๋””ํดํŠธ ๋ฉ”์„œ๋“œ ํ™œ์šฉ ํŒจํ„ด

13.3.1 ์„ ํƒํ˜• ๋ฉ”์„œ๋“œ

์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ(ex. remove)์—๋Š” ๊ธฐ๋Šฅ์„ ๋ฌด์‹œํ•˜๊ณ  ๋นˆ ๊ตฌํ˜„์„ ์ œ๊ณตํ–ˆ์—ˆ๋‹ค.

๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด remove ๊ฐ™์€ ๋ฉ”์„œ๋“œ์— ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค์—์„œ ๋นˆ ๊ตฌํ˜„์„ ์ œ๊ณตํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ž๋ฐ” 8์˜ Iterator ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ remove ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•œ๋‹ค.

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

๊ธฐ๋ณธ ๊ตฌํ˜„์ด ์ œ๊ณต๋˜๋ฏ€๋กœ Iterator ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๋Š” ๋นˆ remove ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†์–ด์กŒ๊ณ , ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

13.3.2 ๋™์ž‘ ๋‹ค์ค‘ ์ƒ์†

๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ๊ธฐ์กด์—๋Š” ๋ถˆ๊ฐ€๋Šฅํ–ˆ๋˜ ๋™์ž‘ ๋‹ค์ค‘ ์ƒ์† ๊ธฐ๋Šฅ๋„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ์ฒ˜๋Ÿผ ํด๋ž˜์Šค๋Š” ๋‹ค์ค‘ ์ƒ์†์„ ์œ„ํ•ด ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ž๋ฐ”์—์„œ ํด๋ž˜์Šค๋Š” ํ•œ ๊ฐœ์˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋งŒ ์ƒ์†ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์—ฌ๋Ÿฌ ๊ฐœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค์Œ์€ ์ž๋ฐ” API์— ์ •์˜๋œ ArrayList ํด๋ž˜์Šค๋‹ค.

1
2
3
4
// ํ•œ ๊ฐœ์˜ ํด๋ž˜์Šค ์ƒ์†, ๋„ค ๊ฐœ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. 
public class ArrayList<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, Serializable {
}

๋‹ค์ค‘ ์ƒ์† ํ˜•์‹

์—ฌ๊ธฐ์„œ ArrayList๋Š” ํ•œ ๊ฐœ์˜ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ณ , ์—ฌ์„ฏ ๊ฐœ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ArrayList๋Š” AbstractList, List, RandomAccess, Cloneable, Serializable, Iterable, Collection์˜ ์„œ๋ธŒ ํ˜•์‹์ด ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋‹ค์ค‘ ์ƒ์†์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ž๋ฐ” 8์—์„œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ตฌํ˜„์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํด๋ž˜์Šค๋Š” ์—ฌ๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ๋™์ž‘(๊ตฌํ˜„ ์ฝ”๋“œ)์„ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

๊ธฐ๋Šฅ์ด ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ตœ์†Œ์˜ ์ธํ„ฐํŽ˜์ด์Šค

ex) ํšŒ์ „X, ํฌ๊ธฐ ์กฐ์ ˆO ๋ชจ์–‘ / ํšŒ์ „O, ์›€์ง์ž„O, ํฌ๊ธฐ ์กฐ์ ˆX

์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ๋จผ์ € setRotationAngle๊ณผ getRotationAngle ๋‘ ๊ฐœ์˜ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ํฌํ•จํ•˜๋Š” Rotatable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•œ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋‹ค์Œ ์ฝ”๋“œ์—์„œ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ setRotationAngle๊ณผ getRotationAngle ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ rotateBy๋„ ๊ตฌํ˜„ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
public interface Rotatable {
    void setRotationAngle(int angleInDegrees);
    int getRotationAngle();
    // rotateBy ๋ฉ”์„œ๋“œ์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„
    default void rotateBy(int angleInDegrees) {
        setRotationAngle((getRotationAngle() + angleInDegrees) % 360);
    }
}

Rotatable์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ํด๋ž˜์Šค๋Š” setRotationAngle๊ณผ getRotationAngle์˜ ๊ตฌํ˜„์„ ์ œ๊ณตํ•ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ rotateBy๋Š” ๊ธฐ๋ณธ ๊ตฌํ˜„์ด ์ œ๊ณต๋˜๋ฏ€๋กœ ๋”ฐ๋กœ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‘ ๊ฐ€์ง€ ์ธํ„ฐํŽ˜์ด์Šค Moveable๊ณผ Resizable์„ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค. ๋‘ ์ธํ„ฐํŽ˜์ด์Šค ๋ชจ๋‘ ๋””ํดํŠธ ๊ตฌํ˜„์„ ์ œ๊ณตํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface Moveable {
    int getX();
    int getY();
    void setX(int x);
    void setY(int y);

    default void moveHorizontally(int distance) {
        setX(getX() + distance);
    }

    default void moveVertically(int distance) {
        setY(getY() + distance);
    }
}
1
2
3
4
5
6
7
8
9
10
11
public interface Resizable {
    int getWidth();
    int getHeight();
    void setWidth(int width);
    void setHeight(int height);
    void setAbsoluteSize(int width, int height);

    default void setRelativeSize(int wFactor, int hFactor) {
        setAbsoluteSize(getWidth() / wFactor, getHeight() / hFactor);
    }
}

์ธํ„ฐํŽ˜์ด์Šค ์กฐํ•ฉ

์›€์ง์ผ ์ˆ˜ ์žˆ๊ณ , ํšŒ์ „ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋Š” ๊ดด๋ฌผ ํด๋ž˜์Šค ๊ตฌํ˜„

1
2
3
public class Monster implements Rotatable, Moveable, Resizable {
    ... // ๋ชจ๋“  ์ถ”์ƒ ๋ฉ”์„œ๋“œ์˜ ๊ตฌํ˜„์€ ์ œ๊ณตํ•ด์•ผ ํ•˜์ง€๋งŒ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ์˜ ๊ตฌํ˜„์€ ์ œ๊ณตํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค
}

Monster ํด๋ž˜์Šค๋Š” Rotatable, Moveable, Resizable ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์†๋ฐ›๋Š”๋‹ค(rotateBy, moveHorizontally, moveVertically, setRelativeSize)

์ƒ์†๋ฐ›์€ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
Monster m = new Monster();  // ์ƒ์„ฑ์ž๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ขŒํ‘œ, ๋†’์ด, ๋„ˆ๋น„, ๊ธฐ๋ณธ ๊ฐ๋„๋ฅผ ์„ค์ •ํ•œ๋‹ค
m.rotateBy(180);        // Rotataable์˜ rotateBy ํ˜ธ์ถœ
m.moveVertically(10);   // Moveable์˜ moveVertically ํ˜ธ์ถœ

์ด๋ฒˆ์—๋Š” ์›€์ง์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ํšŒ์ „ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์—†๋Š” Sun ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•œ๋‹ค.

1
2
3
public class Sun implements Moveable, Rotatable {
    ...
}

์ธํ„ฐํŽ˜์ด์Šค์— ๋””ํดํŠธ ๊ตฌํ˜„์„ ํฌํ•จ์‹œํ‚ค๋ฉด ๋˜ ๋‹ค๋ฅธ ์žฅ์ ์ด ์ƒ๊ธด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด moveVertically์˜ ๊ตฌํ˜„์„ ๋” ํšจ์œจ์ ์œผ๋กœ ๊ณ ์ณ์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ๋””ํดํŠธ ๋ฉ”์„œ๋“œ ๋•๋ถ„์— Moveable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง์ ‘ ๊ณ ์น  ์ˆ˜ ์žˆ๊ณ  ๋”ฐ๋ผ์„œ Moveable์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ํด๋ž˜์Šค๋„ ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝํ•œ ์ฝ”๋“œ๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค(๋ฌผ๋ก  ๊ตฌํ˜„ ํด๋ž˜์Šค์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š์€ ์ƒํ™ฉ์— ํ•œํ•ด์„œ๋‹ค)

13.4 ํ•ด์„ ๊ทœ์น™

๊ฐ™์€ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ฐ–๋Š” ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค์ค‘ ์ƒ์† ๋ฐ›๋Š” ์ƒํ™ฉ์—์„œ ์–ด๋–ค ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ๊ฒƒ์ธ๊ฐ€?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface A {
    default void hello() {
        System.out.println("Hello from A");
    }
}

public interface B extends A {
    default void hello() {
        System.out.println("Hello from B");
    }
}

public class C implements B, A {
    public static void main(String... args) {
        new C().hello();  // ๋ฌด์—‡์ด ์ถœ๋ ฅ๋ ๊นŒ?
    }
}

13.4.1 ์•Œ์•„์•ผ ํ•  ์„ธ ๊ฐ€์ง€ ํ•ด๊ฒฐ ๊ทœ์น™

๋‹ค๋ฅธ ํด๋ž˜์Šค๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ๋ถ€ํ„ฐ ๊ฐ™์€ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ฐ–๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›์„ ๋•Œ๋Š” ์„ธ ๊ฐ€์ง€ ๊ทœ์น™์„ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค.

  1. ํด๋ž˜์Šค๊ฐ€ ํ•ญ์ƒ ์ด๊ธด๋‹ค. ํด๋ž˜์Šค๋‚˜ ์Šˆํผํด๋ž˜์Šค์—์„œ ์ •์˜ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ณด๋‹ค ์šฐ์„ ๊ถŒ์„ ๊ฐ–๋Š”๋‹ค.
  2. 1๋ฒˆ ๊ทœ์น™ ์ด์™ธ์˜ ์ƒํ™ฉ์—์„œ๋Š” ์„œ๋ธŒ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ด๊ธด๋‹ค. ์ƒ์†๊ด€๊ณ„๋ฅผ ๊ฐ–๋Š” ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ๊ฐ™์€ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ฐ–๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ๋Š” ์„œ๋ธŒ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ด๊ธด๋‹ค.

    โ†’ ์ฆ‰, B๊ฐ€ A๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค๋ฉด B๊ฐ€ A๋ฅผ ์ด๊ธด๋‹ค.

  3. ์—ฌ์ „ํžˆ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ์˜ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๊ฒฐ์ •๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์—ฌ๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๊ณ  ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

13.4.2 ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ์„œ๋ธŒ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ด๊ธด๋‹ค

B์™€ A๋Š” hello๋ผ๋Š” ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•œ๋‹ค. ๋˜ํ•œ B๋Š” A๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค.

2์˜ ๊ทœ์น™์— ๋”ฐ๋ผ B์˜ hello๋ฅผ ์„ ํƒํ•œ๋‹ค. ์ฆ‰, โ€˜Hello from Bโ€™๋ฅผ ์ถ”๋ ฅํ•œ๋‹ค.

๋‹ค์Œ์ฒ˜๋Ÿผ C๊ฐ€ D๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ์ง€ ๋ณด์ž

1
2
3
4
5
6
public class D implements A {  }
public class C extends D implements B, A {
    public static void main(String... args) {
        new C().hello(); // ๋ฌด์—‡์ด ์ถœ๋ ฅ๋ ๊นŒ?
    }
}

1๋ฒˆ ๊ทœ์น™์€ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์ด ๊ธด๋‹ค๊ณ  ์„ค๋ช…ํ•œ๋‹ค. D๋Š” hello๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•˜์ง€ ์•Š์•˜๊ณ  ๋‹จ์ˆœํžˆ ์ธํ„ฐํŽ˜์ด์Šค A๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค. ๋”ฐ๋ผ์„œ D๋Š” ์ธํ„ฐํŽ˜์ด์Šค A์˜ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์„ ์ƒ์†๋ฐ›๋Š”๋‹ค.

2๋ฒˆ ๊ทœ์น™์—์„œ๋Š” ํด๋ž˜์Šค๋‚˜ ์Šˆํผํด๋ž˜์Šค์— ๋ฉ”์„œ๋“œ ์ •์˜๊ฐ€ ์—†์„ ๋•Œ๋Š” ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๋Š” ์„œ๋ธŒ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์„ ํƒ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ธํ„ฐํŽ˜์ด์Šค A์˜ hello๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค B์˜ hello ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ B๊ฐ€ A๋ฅผ ์ƒ์†๋ฐ›๋Š” ๊ด€๊ณ„์ด๋ฏ€๋กœ ์ด๋ฒˆ์—๋„ โ€˜Hello from Bโ€™๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

  • Quiz. ํ•ด์„ ๊ทœ์น™์„ ๊ธฐ์–ตํ•˜๋ผ

    ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” ๋ฌด์—‡์ธ๊ฐ€?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      public class D implements A {
          void hello() {
              System.out.println("Hello from D");
          }
      }
        
      public class C extends D implements B, A {
          public static void main(String... args) {
              new C().hello();
          }
      }
    
    • ์ •๋‹ต

      ์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” โ€˜Hello from Dโ€™์ด๋‹ค. ๊ทœ์น™ 1์— ์˜ํ•ด ์Šˆํผํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ ์ •์˜๊ฐ€ ์šฐ์„ ๊ถŒ์„ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

      D๊ฐ€ ๋‹ค์Œ์ฒ˜๋Ÿผ ๊ตฌํ˜„๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.

      1
      2
      3
      
        public abstract class D implements A {
            public abstract void hello();
        }
      

      ๊ทธ๋Ÿฌ๋ฉด A์—์„œ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  C๋Š” hello๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

13.4.3 ์ถฉ๋Œ ๊ทธ๋ฆฌ๊ณ  ๋ช…์‹œ์ ์ธ ๋ฌธ์ œ ํ•ด๊ฒฐ

์ด๋ฒˆ์—๋Š” B๊ฐ€ A๋ฅผ ์ƒ์†๋ฐ›์ง€ ์•Š๋Š” ์ƒํ™ฉ์ด๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface A {
    default void hello() {
        System.out.println("Hello from A");
    }
}

public interface B {
    default void hello() {
        System.out.println("Hello from B");
    }
}

public class C implements B, A {  }

์ด๋ฒˆ์—๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ„ ์ƒ์† ๊ด€๊ณ„๊ฐ€ ์—†์œผ๋ฏ€๋กœ 2๋ฒˆ ๊ทœ์น™์„ ์ ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ A์™€ B์˜ hello ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌ๋ณ„ํ•  ๊ธฐ์ค€์ด ์—†๋‹ค.

๋”ฐ๋ผ์„œ ์ž๋ฐ” ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์–ด๋–ค ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ• ์ง€ ์•Œ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ โ€œError: class C inherits unrelated defaults for hello() from types B and Aโ€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ถฉ๋Œ ํ•ด๊ฒฐ

ํด๋ž˜์Šค์™€ ๋ฉ”์„œ๋“œ ๊ด€๊ณ„๋กœ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์—์„œ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†๋‹ค.

โ‡’ ํด๋ž˜์Šค C์—์„œ hello ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•œ ๋‹ค์Œ์— ํ˜ธ์ถœํ•˜๋ ค๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค.

์ž๋ฐ” 8์—์„œ๋Š” X.super.m(โ€ฆ) ํ˜•ํƒœ์˜ ์ƒˆ๋กœ์šด ๋ฌธ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ X๋Š” ํ˜ธ์ถœํ•˜๋ ค๋Š” ๋ฉ”์„œ๋“œ m์˜ ์Šˆํผ ์ธํ„ฐํŽ˜์ด์Šค๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ์ฒ˜๋Ÿผ C์—์„œ B์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
public class C implements B, A {
    void hello() {
        B.super.hello(); // ๋ช…์‹œ์ ์œผ๋กœ ์ธํ„ฐํŽ˜์ด์Šค B์˜ ๋ฉ”์„œ๋“œ ์„ ํƒ
    }
}
  • Quiz. ๊ฑฐ์˜ ๋น„์Šทํ•œ ์‹œ๊ทธ๋‹ˆ์ฒ˜

    ์ธํ„ฐํŽ˜์ด์Šค A์™€ B๊ฐ€ ๋‹ค์Œ์ฒ˜๋Ÿผ ์ •์˜๋˜์–ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
      public interface A {
          default Number getNumber() {
              return 10;
          }
      }
        
      public interface B {
          default Integer getNumber() {
              return 42;
          }
      }
        
      public class C implements B, A {
          public static void main(String... args) {
              System.out.println(new C().getNumber()));
          }
      }
    

    ํ”„๋กœ๊ทธ๋žจ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š”?

    • ์ •๋‹ต

      C๋Š” A์™€ B ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค C์—์„œ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

13.4.4 ๋‹ค์ด์•„๋ชฌ๋“œ ๋ฌธ์ œ

1
2
3
4
5
6
7
8
9
10
11
12
public interface A {
    default void hello() {
        System.out.println("Hello from A");
    }
}
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();  // ๋ฌด์—‡์ด ์ถœ๋ ฅ๋ ๊นŒ?
    }
}

ํ•ด๋‹น ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋‹ค์ด์•„๋ชฌ๋“œ ๋ฌธ์ œ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. D๋Š” B์™€ C ์ค‘ ๋ˆ„๊ตฌ์˜ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ ์ •์˜๋ฅผ ์ƒ์†๋ฐ›์„๊นŒ? ์‹ค์ œ๋กœ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ ์„ ์–ธ์€ ํ•˜๋‚˜๋ฟ์ด๋‹ค. A๋งŒ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๊ณ  ์žˆ๋‹ค. ๊ฒฐ๊ตญ ํ”„๋กœ๊ทธ๋žจ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” โ€˜Hello from Aโ€™๊ฐ€ ๋œ๋‹ค.

B์™€ C ๋ชจ๋‘ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ hello ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•œ๋‹ค๋ฉด ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ๋‘˜ ์ค‘ ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

๋‹ค์Œ์ฒ˜๋Ÿผ ์ธํ„ฐํŽ˜์ด์Šค C์— ์ถ”์ƒ ๋ฉ”์„œ๋“œ hello(๋””ํดํŠธ ๋ฉ”์„œ๋“œ ์•„๋‹˜!)๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์–ด๋–ค์ผ์ด ๋ฐœ์ƒํ• ๊นŒ(A์™€ B์—๋Š” ์•„๋ฌด ๋ฉ”์„œ๋“œ๋„ ์ •์˜ํ•˜์ง€ ์•Š๋Š”๋‹ค)?

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

C๋Š” A๋ฅผ ์ƒ์†๋ฐ›์œผ๋ฏ€๋กœ C์˜ ์ถ”์ƒ ๋ฉ”์„œ๋“œ hello๊ฐ€ A์˜ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ hello๋ณด๋‹ค ์šฐ์„ ๊ถŒ์„ ๊ฐ–๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ, ํด๋ž˜์Šค D๊ฐ€ ์–ด๋–ค hello๋ฅผ ์‚ฌ์šฉํ• ์ง€ ๋ช…์‹œ์ ์œผ๋กœ ์„ ํƒํ•˜์—ฌ ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

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