Home 다형성
Post
Cancel

다형성

다형성

  • 하나의 객체가 여러개의 자료형 타입을 가질 수 있는 것

    인터페이스에서 사용한 코드에 추가로 ‘경비원’ 클래스를 형성,
    경비원 클래스는 동물을 짖게(barkAnimal) 하여 건물을 지킨다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Bouncer {
    void barkAnimal(Animal animal) {
        if (animal instanceof Tiger) {
            System.out.println("어흥");
        } else if (animal instanceof Lion) {
            System.out.println("으르렁");
        }
    }
}

public class Sample {
    public static void main(String[] args) {
        Tiger tiger = new Tiger();
        Lion lion = neaw Lion();

        Bouncer bouncer= new Bouncer();
        bouncer.barkAnimal(tiger); // 어흥
        bouncer.barkAnimal(lion); // 으르렁
    }
} 
  • instanceof: 어떤 객체가 특정 클래스의 객체인지를 조사할 때 사용되는 자바의 내장 명령어
    • animal instanceof Tiger 는 “animal 객체는 Tiger 클래스로 만들어진 객체인가?”를 묻는 조건문
    • IS-A 관계에서 배웠듯, tiger과 lion은 animal 객체로 볼 수 있다.



위 코드를 interface를 이용하여 개선

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
interface Barkable {
    void bark();
}

class Tiger extends Animal implements Predator, Barkable {
    public String getFood() {
        return "apple";
    }

    public void bark() {
        System.out.println("어흥");
    }
}

class Lion extends Animal implements Predator, Barkable {
    public String getFood() {
        return "banana";
    }

    public void bark() {
        System.out.println("으르렁");
    }
}


class Bouncer {
    void barkAnimal(Barkable animal) {  // Animal 대신 Barkable을 사용
        animal.bark();
    }
}

  • 위 코드의 tiger, lion 객체는 각각 Tiger, Lion 클래스의 객체이면서, Animal 클래스의 객체이기도 하고, Barkable, Predator 인터페이스의 객체이기도 하다.
    • 이러한 이유로 barkAnimal 메소드의 입력 자료형을 Animal에서 Barkable 로 바꾸어 사용할 수 있는 것



Tiger 클래스의 객체는 아래와 같이 여러가지 자료형으로 표현 가능

1
2
3
4
Tiger tiger = new Tiger();  // Tiger is a Tiger
Animal animal = new Tiger();  // Tiger is a Animal
Predator predator = new Tiger();  // Tiger is a Predator
Barkable barkable = new Tiger();  // Tiger is a Barkable

주의사항

  • Predator 로 선언된 predator 객체와 Barkable 로 선언된 barkable 객체는 사용할 수 있는 메소드가 서로 다르다.
    • predator 객체는 getFood() 메소드만 사용가능
    • barkable 객체는 bark() 메소드만 호출이 가능
  • getFood 메소드와 bark 메소드를 모두 사용하고 싶다면?
    • Predator, Barkable 인터페이스를 구현한 Tiger 로 선언된 tiger 객체를 그대로 사용 (여러개의 인터페이스(Predator, Barkable)를 동시에 상속가능)
      ※ 일반 클래스는 단일상속만 가능
    • getFood, bark 메소드를 모두 포함하는 새로운 인터페이스를 새로 만들어 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface Barkable {
    void bark();
}

interface BarkablePredator extends Predator, Barkable {
}

class Lion extends Animal implements BarkablePredator {
    public String getFood() {
        return "banana";
    }

    public void bark() {
        System.out.println("으르렁");
    }
}



전체 소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
interface Predator {
    String getFood();

    default void printFood() {
        System.out.printf("my food is %s\n", getFood());
    }

    int LEG_COUNT = 4;  // 인터페이스 상수

    static int speed() {
        return LEG_COUNT * 30;
    }
}

interface Barkable {
    void bark();
}

interface BarkablePredator extends Predator, Barkable {
}

class Animal {
    String name;

    void setName(String name) {
        this.name = name;
    }
}

class Tiger extends Animal implements Predator, Barkable {
    public String getFood() {
        return "apple";
    }

    public void bark() {
        System.out.println("어흥");
    }
}

class Lion extends Animal implements BarkablePredator {
    public String getFood() {
        return "banana";
    }

    public void bark() {
        System.out.println("으르렁");
    }
}

class ZooKeeper {
    void feed(Predator predator) {
        System.out.println("feed " + predator.getFood());
    }
}

class Bouncer {
    void barkAnimal(Barkable animal) {
        animal.bark();
    }
}

public class Sample {
    public static void main(String[] args) {
        Tiger tiger = new Tiger();
        Lion lion = new Lion();

        Bouncer bouncer = new Bouncer();
        bouncer.barkAnimal(tiger);
        bouncer.barkAnimal(lion);
    }
}
참고자료

점프 투 자바 - 객체지향 프로그래밍