스크린샷 2025-08-18 오전 9.57.10.png

package com.haenin.section02.extend;

public class Application1 {
    public static void main(String[] args) {
        /* 목표, 제네릭 클래스를 좀 더 활용하는 예제를 이해할 수 있다. */
//        RabbitFarm<Animal> farm1 = new RabbitFarm<Animal>();
//        RabbitFarm<Mammal> farm2 = new RabbitFarm<>();
//        RabbitFarm<Snake> farm3 = new RabbitFarm<>();

        /* 설명. <T extends Rabbit>에 의해 Rabbit 및 하위 타입으로만
        *       제네릭 객체가 생성 가능하면 이후에는 객체별 다른 타입일 수 있다.*/
        RabbitFarm<Rabbit> farm4 = new RabbitFarm<>();
        RabbitFarm<Bunny> farm5 = new RabbitFarm<>();
        RabbitFarm<DrunkenBunny> farm6 = new RabbitFarm<>();

        farm4.setRabbit(new Rabbit());
        farm4.getRabbit().cry();
        farm4.setRabbit(new Bunny());
        farm4.getRabbit().cry();

//        farm5.setRabbit(new Rabbit()); //필기. 컴파일 에러 발생
        farm5.setRabbit(new Bunny());
        farm5.getRabbit().cry();
    }

}

package com.haenin.section02.extend;

public interface Animal {
}
package com.haenin.section02.extend;

public class Mammal implements Animal{
}
package com.haenin.section02.extend;

public class Reptile implements Animal{
}
package com.haenin.section02.extend;

public class Snake extends Reptile{
}
package com.haenin.section02.extend;

public class Rabbit extends Mammal{
    public void cry(){
        System.out.println("토끼가 울음소리를 냅니다. 끾끾!");
    }
}
package com.haenin.section02.extend;

public class Bunny extends Rabbit{
    @Override
    public void cry() {
        System.out.println("바니바니 당근당근!");
    }
}
package com.haenin.section02.extend;

public class DrunkenBunny extends Rabbit{
    @Override
    public void cry() {
        System.out.println("봐니봐니@ 당근당근!@");
    }
}

package com.haenin.section02.extend;
/* 설명. RabbitFarm 제네릭 클래스는 Rabbit 또는 Rabbit 하위 타입으로만 제네릭 타입을 지정할 수 있다. */
public class RabbitFarm<T extends Rabbit> {
    private T rabbit;

    public RabbitFarm() {
    }

    public RabbitFarm(T rabbit) {
        this.rabbit = rabbit;
    }

    public T getRabbit() {
        return rabbit;
    }

    public void setRabbit(T rabbit) {
        this.rabbit = rabbit;
    }
}

package com.haenin.section02.extend;

public class Application2 {
    public static void main(String[] args) {

        /* 목표, 와일드카드에 대해 이해할 수 있다. */
        WildCardFarm wildCardFarm = new WildCardFarm();

//        Rabbit r = new Rabbit();
//        RabbitFarm<Rabbit> rFarm = new RabbitFarm<>();
//
//        wildCardFarm.anyType(rFarm);
        wildCardFarm.anyType(new RabbitFarm<Rabbit>(new Rabbit()));
        wildCardFarm.anyType(new RabbitFarm<Bunny>(new Bunny()));
        wildCardFarm.anyType(new RabbitFarm<DrunkenBunny>(new DrunkenBunny()));

//        wildCardFarm.extendsType(rFarm);
//        wildCardFarm.extendsType(new RabbitFarm<Rabbit>(new Rabbit()));
        wildCardFarm.extendsType(new RabbitFarm<Bunny>(new Bunny()));
//        wildCardFarm.extendsType(new RabbitFarm<DrunkenBunny>(new DrunkenBunny()));

//        wildCardFarm.superType(rFarm);
        wildCardFarm.superType(new RabbitFarm<Rabbit>(new Rabbit()));
        wildCardFarm.superType(new RabbitFarm<Bunny>(new Bunny()));
//        wildCardFarm.superType(new RabbitFarm<DrunkenBunny>(new DrunkenBunny()));

    }

}