๊ด€๋ฆฌ ๋ฉ”๋‰ด

๐‘†๐‘ข๐‘›๐‘ โ„Ž๐‘–๐‘›๐‘’ ๐‘Ž๐‘“๐‘ก๐‘’๐‘Ÿ ๐‘Ÿ๐‘Ž๐‘–๐‘›โœง

[Java] Generic Method ์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ ๋ณธ๋ฌธ

๐—ฃ๐—ฟ๐—ผ๐—ด๐—ฟ๐—ฎ๐—บ๐—บ๐—ถ๐—ป๐—ด๐Ÿ’ป/๐‰๐š๐ฏ๐š

[Java] Generic Method ์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ

๐ŸคRyusun๐Ÿค 2022. 10. 12. 15:05

โญ์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ(generic method)

 

  • ์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ๋ž€ ๋ฉ”์†Œ๋“œ์˜ ์„ ์–ธ๋ถ€์— ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ๋ฉ”์†Œ๋“œ๋ฅผ ์˜๋ฏธ
  • ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ƒ์†๊ด€๊ณ„์™€ ์ƒ๊ด€์—†์ด ๋‹ค์–‘ํ•˜๊ฒŒ ์ฃผ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

  • ํ˜•ํƒœ
    • public class ํด๋ž˜์Šค๋ช…<T> { ... }
    • public interface ์ธํ„ฐํŽ˜์ด์Šค๋ช…<T> { ... } 

 

  • ํŠน์ง•
    • ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์ด๋‚˜ ๋ฆฌํ„ด ํƒ€์ž…์— ๋Œ€ํ•œ ์ •์˜๋ฅผ ์™ธ๋ถ€๋กœ ๋ฏธ๋ฃธ
    • ํƒ€์ž…์— ๋Œ€ํ•œ ์•ˆ์ •์„ฑ๊ณผ ์œ ์—ฐ์„ฑ ํ™•๋ณด
    • ๋งŒ์•ฝ ์ตœ์ƒ์œ„ ํด๋ž˜์Šค Object๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š”๋‹ค๋ฉด ๊ฐ์ฒด๋ณ€์ˆ˜์˜ ์‹ค์ œ ์ธ์Šคํ„ด์Šค ํ•„๋“œ๋‚˜ ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ• ๋•Œ ํ˜•๋ณ€ํ™˜ ํ•„์š”ํ•˜๋‹ค.
    • ๋˜ํ•œ Object ๊ฐ์ฒด๋ณ€์ˆ˜์˜ ์‹ค์ œ ์ธ์Šคํ„ด์Šค ํ•„๋“œ๋‚˜ ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ํ˜•๋ณ€ํ™˜์„ ์ž˜๋ชปํ•  ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋ฅผ ์žก์ง€ ๋ชปํ•œ๋‹ค.

 

  • ์ œ๋„ˆ๋ฆญ ์žฅ์ 
    • ๋ฐ์ดํ„ฐ ํ˜• ๋ณ€ํ™˜ ์ œ๊ฑฐ
    • ์ปดํŒŒ์ผ์‹œ ๋ฐ์ดํ„ฐ ํƒ€์ž… ์ฒดํฌ ๊ฐ€๋Šฅ

 

์˜ˆ์‹œ 

import java.util.Objects;

public class GiftBox<T> {
    private T gift;

    public GiftBox() {
    }

    public GiftBox(T gift) {
        this.gift = gift;
    }

    public T getGift() {
        return gift;
    }

    public void setGift(T gift) {
        this.gift = gift;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        GiftBox<?> that = (GiftBox<?>) o;
        return gift.equals(that.gift);
    }

    @Override
    public int hashCode() {
        return Objects.hash(gift);
    }

    @Override
    public String toString() {
        return "RandomGiftBox{" +
                "gift=" + gift +
                '}';
    }
}
import me.day13.generic.basics.gift.Note;
import me.day13.generic.basics.gift.Pen;
import me.day13.generic.basics.gift.SmartPhone;
import me.day13.generic.basics.gift.Tablet;

    public class GenericExample {
        public static void main(String[] args) {
            GiftBox<Note> noteBox = new GiftBox<>();
            noteBox.setGift(new Note("1001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", true));
            System.out.println("noteBox = " + noteBox);

            // ํ˜• ๋ณ€ํ™˜ ํ›„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ
            noteBox.getGift().setHasLine(false); // ํ˜•๋ณ€ํ™˜ ๋ถˆํ•„์š”.
//        ((Pen)noteBox.getGift()).setInkColor("๋นจ๊ฐ•"); // ์ปดํŒŒ์ผ๋Ÿฌ ์˜ค๋ฅ˜.
            System.out.println("noteBox = " + noteBox);
            System.out.println();

            GiftBox<Pen> penBox = new GiftBox<>();
            penBox.setGift(new Pen("2001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", "๊ฒ€์ •"));
            System.out.println("penBox = " + penBox);

            penBox.getGift().setInkColor("ํŒŒ๋ž‘"); // ํ˜•๋ณ€ํ™˜ ๋ถˆํ•„์š”.
            System.out.println("penBox = " + penBox);
            System.out.println();

            GiftBox<Tablet> tableBox = new GiftBox<>();
            tableBox.setGift(new Tablet("3001", "APPLE", "IPAD-AIR3", true));
            System.out.println("tableBox = " + tableBox);

            tableBox.getGift().setHasPencil(false);
            System.out.println("tableBox = " + tableBox);
            System.out.println();


            GiftBox<SmartPhone> smartPhoneBox = new GiftBox<>();
            smartPhoneBox.setGift(new SmartPhone("4001", "SAMSUNG", "Z-FOLD4", 3, 20));
            System.out.println("smartPhoneBox = " + smartPhoneBox);

            smartPhoneBox.getGift().setNumOfCameras(5);
            smartPhoneBox.getGift().setNumOfSensors(30);
            System.out.println("smartPhoneBox = " + smartPhoneBox);
            System.out.println();
        }
    }

 

  • ๋ฉ€ํ‹ฐ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ
    • ์ œ๋„ˆ๋ฆญ ํƒ€์ž…์€ ๋‘ ๊ฐœ ์ด์ƒ ๋ฉ€ํ‹ฐ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    • ํ˜•ํƒœ

์ถœ์ฒ˜:&nbsp;https://devlog-wjdrbs96.tistory.com/201

์ œ๋„ˆ๋ฆญ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…: https://devlog-wjdrbs96.tistory.com/201

 

์˜ˆ์‹œ 

public interface Utils {
    static <T> Box<T> boxing(T item) {

// <T>๋Š” ์ œ๋„ˆ๋ฆญ ๋ฉ”์„œ๋“œ. ์ œ๋„ˆ๋ฆญ ๋ฉ”์„œ๋“œ๋Š” ํƒ€์ž…์ด ๋ณ€ํ•˜๋Š” ๋ฉ”์„œ๋“œ. ๋งŒ์•ฝ T์— Note๊ฐ€ ๋“ค์–ด์˜ค๋ฉด Note๊ฐ€ boxing๋˜์–ด์„œ Noteํƒ€์ž…์˜ Box๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š”๊ฒƒ์ด๋‹ค. 

<T> = ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์ œ๋„ˆ๋ฆญ ๋ฉ”์„œ๋“œ ๋ผ๊ณ  ์˜๋ฏธ

<T>  = ๋ฐ˜ํ™˜๋˜๋Š” Box ํƒ€์ž…์„ ์˜๋ฏธ

T = ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์˜๋ฏธ

๋”ฐ๋ผ์„œ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด boxing์ด ๋˜๊ณ  ์ด ๋ฐ˜ํ™˜box๋ฅผ ํ†ตํ•ด์„œ 
        Box<T> box = new Box<>();
        box.setItem(item);
        return box;
    }

ํด๋ž˜์Šค์— ์ œ๋„ˆ๋ฆญ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒˆ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ• ๋•Œ ํƒ€์ž…์„ ์ •ํ•ด์ค„์ˆ˜ ์ž‡๋Š”๋ฐ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ƒˆ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์„ ๋ชปํ•˜๊ธฐ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์„œ ํƒ€์ž…์„ ์ •ํ•ด์ฃผ๋Š”๊ฒƒ์ด๋‹ค. 

    static <T> void decoration(Box<T> box, Decorations decoration) {
        System.out.println(box + " is decorated with "+ decoration);
    }

    static <T> T unboxing(Box<T> box) {
        T item = box.getItem();
        return item;
    }
}

 

  • ์ œํ•œ๋œ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ
    • bounded type parameter
    • <ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ extends ์ƒ์œ„ํƒ€์ž…>
      • ์ƒ์† ๊ด€๊ณ„๋„์—์„œ ์ƒ์œ„ ํƒ€์ž… ์ดํ•˜์— ์žˆ๋Š” ํƒ€์ž…์ด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์˜ฌ ์ˆ˜ ์žˆ์Œ
      • ์ƒํ•œ ํƒ€์ž… ์ œํ•œ
    • <ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ super ํ•˜์œ„ํƒ€์ž…>
      • ์ƒ์† ๊ด€๊ณ„๋„์—์„œ ํ•˜์œ„ ํƒ€์ž… ์ด์ƒ์— ์žˆ๋Š” ํƒ€์ž…์ด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์˜ฌ ์ˆ˜ ์žˆ์Œ
      • ํ•˜ํ•œ ํƒ€์ž… ์ œํ•œ
import java.util.Arrays;
import java.util.Objects;

public class Gifts<E extends Item> {

    private static final int DEFULAT_SIZE = 10;
    private int size;

    private E[] gifts;
    private int count;

    public Gifts() {
        gifts = (E[]) new Item[DEFULAT_SIZE];
        this.size = DEFULAT_SIZE;
    }

    public Gifts(int size) {
        gifts = (E[]) new Item[size];
        this.size = size;
    }

    public E get(int i) {
        return gifts[i];
    }

    public void add(E element) { // ํŠน์ •์ธ๋ฑ์Šค์— ์š”์†Œ ์ถ”๊ฐ€ํ•˜๊ธฐ
        if (count < size) {
            gifts[count] = element;
            count++;
        } else {
            E[] origin = Arrays.copyOf(gifts, count); 
            // Arrays.copy(๋ฐฐ์—ด, ๊ฐœ์ˆ˜) = ๋ฐฐ์—ด์„ ๊ฐœ์ˆ˜๋งŒํผ ๋ณต์‚ฌํ•˜๋Š” ํ•จ์ˆ˜
            size *= 2;
            gifts = Arrays.copyOf(origin, size);
            add(element);
        }
    }


    public void remove(E element) { // ํŠน์ •์ธ๋ฑ์Šค๊ฐ’ ์‚ญ์ œํ•˜๊ธฐ
        int elementIndex = -1;
        for (int i = 0; i < count; i++) {
            if (gifts[i] != null) {
                if (gifts[i].equals(element)) {
                    elementIndex = i;
                }
            }
        }
        if (elementIndex == -1) {// ์ดˆ๊ธฐ๊ฐ’์ด ์•ˆ๋ณ€ํ–ˆ์œผ๋ฉด ์ฐพ๋Š” ์ธ๋ฑ์Šค๊ฐ€ ์—†๋‹ค๋Š” ์˜๋ฏธ
            System.out.println(element + " can't be found.");
        } else {
            gifts[elementIndex] = null;
            for (int i = elementIndex+1; i < count; i++) {
                gifts[i-1] = gifts[i];
            }
            count--;

            System.out.println(element + " removed successfully.");
        }
    }


    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public E[] getGifts() {
        return gifts;
    }

    public void setGifts(E[] gifts) {
        this.gifts = gifts;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Gifts<?> that = (Gifts<?>) o;
        return size == that.size && count == that.count && Arrays.equals(gifts, that.gifts);
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(size, count);
        result = 31 * result + Arrays.hashCode(gifts);
        return result;
    }

    @Override
    public String toString() {
        return "RandomGiftBox{" +
                "size=" + size +
                ", gifts=" + Arrays.toString(gifts) +
                ", count=" + count +
                '}';
    }
}
import me.day13.generic.extend.gift.*;

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

        Gifts<Note> randomNotes = new Gifts<>();
        randomNotes.add(new Note("1001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", true));
        randomNotes.add(new Note("2001", "๋ฐ”๋ฅธ์†", false));
        randomNotes.add(new Note("3001", "๋ฐ”๋ฅธ์†", true));
        randomNotes.add(new Note("4001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", false));


        for (int i = 0; i < randomNotes.getCount(); i++) {
            randomNotes.get(i).setHasLine(true);
            System.out.println("randomNotes.getGifts().get(i) = " + randomNotes.get(i));
        }

        System.out.println();
        randomNotes.remove(new Note("1001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", true));
        randomNotes.remove(new Note("2001", "๋ฐ”๋ฅธ์†", true));
        randomNotes.remove(new Note("3001", "๋ฐ”๋ฅธ์†", true));
        randomNotes.remove(new Note("4001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", true));
        randomNotes.remove(new Note("4001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", true));
        System.out.println();
        System.out.println();

        //////////////////////////////////////////////////////////////////////////////////////////


        Gifts<Pen> randomPens = new Gifts<>();
        randomPens.add(new Pen("1001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", "๋นจ๊ฐ•"));
        randomPens.add(new Pen("2001", "๋ฐ”๋ฅธ์†", "๊ฒ€์ •"));
        randomPens.add(new Pen("3001", "๋ฐ”๋ฅธ์†", "๊ฒ€์ •"));
        randomPens.add(new Pen("4001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", "ํŒŒ๋ž‘"));


        for (int i = 0; i < randomPens.getCount(); i++) {
            randomPens.get(i).setInkColor("๊ฒ€์ •");
            System.out.println("randomPens.getGifts().get(i) = " + randomPens.get(i));
        }

        System.out.println();
        randomPens.remove(new Pen("1001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", "๊ฒ€์ •"));
        randomPens.remove(new Pen("2001", "๋ฐ”๋ฅธ์†", "๊ฒ€์ •"));
        randomPens.remove(new Pen("3001", "๋ฐ”๋ฅธ์†", "๊ฒ€์ •"));
        randomPens.remove(new Pen("4001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", "๊ฒ€์ •"));
        randomPens.remove(new Pen("4001", "๋ชจ๋‹๊ธ€๋กœ๋ฆฌ", "๊ฒ€์ •"));
        System.out.println();
        System.out.println();

        //////////////////////////////////////////////////////////////////////////////////////////


        Gifts<Tablet> randomTables = new Gifts<>();
        randomTables.add(new Tablet("1001", "SAMSUNG", "GALAXY-TAB S8", true));
        randomTables.add(new Tablet("2001", "APPLE", "IPAD-AIR3", false));
        randomTables.add(new Tablet("3001", "APPLE", "IPAD-PRO3", false));
        randomTables.add(new Tablet("4001", "SAMSUNG", "GALAXY-TAB S8+", true));

        for (int i = 0; i < randomTables.getCount(); i++) {
            randomTables.get(i).setHasPencil(true);
            System.out.println("randomTables.getGifts().get(i) = " + randomTables.get(i));
        }

        System.out.println();
        randomTables.remove(new Tablet("1001", "SAMSUNG", "GALAXY-TAB S8", true));
        randomTables.remove(new Tablet("2001", "APPLE", "IPAD-AIR3", true));
        randomTables.remove(new Tablet("3001", "APPLE", "IPAD-PRO3", true));
        randomTables.remove(new Tablet("4001", "SAMSUNG", "GALAXY-TAB S8+", true));
        randomTables.remove(new Tablet("4001", "SAMSUNG", "GALAXY-TAB S8+", true));
        System.out.println();
        System.out.println();

        //////////////////////////////////////////////////////////////////////////////////////////


        Gifts<SmartPhone> randomSmartPhone = new Gifts<>();
        randomSmartPhone.add(new SmartPhone("1001", "SAMSUNG", 3, 20));
        randomSmartPhone.add(new SmartPhone("2001", "LG", 2, 10));
        randomSmartPhone.add(new SmartPhone("3001", "LG", 3, 10));
        randomSmartPhone.add(new SmartPhone("4001", "SAMSUNG", 2, 15));

        for (int i = 0; i < randomSmartPhone.getCount(); i++) {
            randomSmartPhone.get(i).setNumOfCameras(3);
            randomSmartPhone.get(i).setNumOfSensors(20);
            System.out.println("randomSmartPhone.getGifts().get(i) = " + randomSmartPhone.get(i));
        }

        System.out.println();
        randomSmartPhone.remove(new SmartPhone("1001", "SAMSUNG", 3, 20));
        randomSmartPhone.remove(new SmartPhone("2001", "LG", 3, 20));
        randomSmartPhone.remove(new SmartPhone("3001", "LG", 3, 20));
        randomSmartPhone.remove(new SmartPhone("4001", "SAMSUNG", 3, 20));
        randomSmartPhone.remove(new SmartPhone("4001", "SAMSUNG", 3, 20));
        System.out.println();
        System.out.println();
        
    }
}

E ์ž๋ฆฌ์— ์‚ฌ์šฉํ•  ํƒ€์ž…์„ ์“ฐ๋ฉด ๋œ๋‹ค. 

โญ์™€์ผ๋“œ์นด๋“œ

  • ์ฝ”๋“œ์—์„œ ? ๋กœ ์‚ฌ์šฉ
  • ์ œ๋„ˆ๋ฆญ ํƒ€์ž…์„ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๊ฐ’์ด๋‚˜ ๋ฆฌํ„ด ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž… ๋Œ€์‹ ์— ์™€์ผ๋“œ ์นด๋“œ๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ํด๋ž˜์Šค/์ธํ„ฐํŽ˜์ด์Šค๋ช…<?>
    • Unbounded Wildcards (์ œํ•œ์—†์Œ)
    • ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋Œ€์น˜ํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์œผ๋กœ ๋ชจ๋“  ํด๋ž˜์Šค/์ธํ„ฐํŽ˜์ด์Šค ์˜ฌ ์ˆ˜ ์žˆ์Œ
  • ํด๋ž˜์Šค/์ธํ„ฐํŽ˜์ด์Šค๋ช…<? extends ์ƒ์œ„ํƒ€์ž…>
    • Upper Bounded Wildcards (์ƒ์œ„ ํด๋ž˜์Šค ์ œํ•œ)
    • ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋Œ€์น˜ํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์œผ๋กœ ์ƒ์œ„ ํƒ€์ž…์ด๋‚˜ ์ƒ์œ„ ํƒ€์ž… ์ดํ•˜์˜ ํƒ€์ž…๋งŒ ์˜ฌ ์ˆ˜ ์žˆ์Œ
  • ํด๋ž˜์Šค/์ธํ„ฐํŽ˜์ด์Šค๋ช…<? super ํ•˜์œ„ํƒ€์ž…>
    • Lower Bounded Wildcards (ํ•˜์œ„ ํด๋ž˜์Šค ์ œํ•œ)
    • ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋Œ€์น˜ํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์œผ๋กœ ํ•˜์œ„ ํƒ€์ž…์ด๋‚˜ ํ•˜์œ„ ํƒ€์ž… ์ด์ƒ์˜ ํƒ€์ž…๋งŒ ์˜ฌ ์ˆ˜ ์žˆ์Œ
  • <?>           // ํƒ€์ž… ๋ณ€์ˆ˜์— ๋ชจ๋“  ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
  • <? extends T> // T ํƒ€์ž…๊ณผ T ํƒ€์ž…์„ ์ƒ์†๋ฐ›๋Š” ์ž์† ํด๋ž˜์Šค ํƒ€์ž…๋งŒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
  • <? super T>   // T ํƒ€์ž…๊ณผ T ํƒ€์ž…์ด ์ƒ์†๋ฐ›์€ ์กฐ์ƒ ํด๋ž˜์Šค ํƒ€์ž…๋งŒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.

 

์˜ˆ์‹œ

import java.util.Arrays;
import java.util.Objects;



public class Course<T> {

    public enum RegisterStudentType { ANIMAL, PERSON, STUDENT, HIGH_STUDENT, UNIV_STUDENT, WORKER }

    private String courName;
    private RegisterStudentType registerStudentType;
    private T[] registerStudents;
    private int count = 0;
    private int size = 0;

    public Course() {
    }

    public Course(String courName, RegisterStudentType registerStudentType, int size) {
        this.courName = courName;
        this.registerStudentType = registerStudentType;
        this.registerStudents = (T[]) new Object[size];
        this.size = size;
    }

    public String getCourName() {
        return courName;
    }

    public void setCourName(String courName) {
        this.courName = courName;
    }

    public RegisterStudentType getRegisterStudentType() {
        return registerStudentType;
    }

    public void setRegisterStudentType(RegisterStudentType registerStudentType) {
        this.registerStudentType = registerStudentType;
    }

    public T[] getRegisterStudents() {
        return registerStudents;
    }

    public void setRegisterStudents(T[] registerStudents) {
        this.registerStudents = registerStudents;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public void add(T t) {
        if (count < size) {
            registerStudents[count] = (T) t;
            count++;

            System.out.println(t + " is added successfully.");
        } else {
            T[] copied = Arrays.copyOf(registerStudents, size);
            size *= 2;
            registerStudents = Arrays.copyOf(copied, size);
            add(t);
        }

    }

    public T remove(T t) {
        if (t == null) {
            System.out.println(t +" can't be removed successfully.");
            return null;
        }

        int index = -1;
        for (int i = 0; i < count; i++) {
            if (t instanceof Person) {
                if (registerStudents[i] != null) {
                    if (registerStudents[i].equals(t)) {
                        index = i;
                    }
                }
            }
        }
        T removeStudent = registerStudents[index];
        registerStudents[index] = null;

        for (int i = index+1; i < count; i++) {
            registerStudents[i-1] = registerStudents[i];
        }

        System.out.println(removeStudent + " is removed successfully.");
        return removeStudent;
    }



    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Course<?> course = (Course<?>) o;
        return courName.equals(course.courName) && registerStudentType == course.registerStudentType && Arrays.equals(registerStudents, course.registerStudents);
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(courName, registerStudentType);
        result = 31 * result + Arrays.hashCode(registerStudents);
        return result;
    }

    @Override
    public String toString() {
        return "Course{" +
                "courName='" + courName + '\'' +
                ", registerStudentType=" + registerStudentType +
                ", registerStudents=" + Arrays.toString(registerStudents)  +
                '}';
    }
}
public interface CourseUtils {
    static void registerPersonCourse(Course<? extends Person> course) {
        System.out.println(course + " is registered successfully.\n\n");
    }
    static void registerAnimalCourse(Course<? extends Animal> course) {
        System.out.println(course + " is registered successfully.\n\n");
    }

}
public class GenericWildCardExample {
    public static void main(String[] args) {
        Course<Person> personCourse = new Course<>("์ œํ…Œํฌ ์‹œ์ž‘ํ•˜๊ธฐ", Course.RegisterStudentType.PERSON, 5);
        Course<Student> studentCourse = new Course<>("์Šคํฌ๋ž˜์น˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ", Course.RegisterStudentType.STUDENT, 5);
        Course<Worker>  workerCourse = new Course<>("์‹ค๋ฌด ์ž๋™ํ™”๋ฅผ ์œ„ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ", Course.RegisterStudentType.WORKER, 5);
        Course<HighStudent> highStudentCourse = new Course<>("๋Œ€ํ•™ ์ž…์‹œ๋ฅผ ์œ„ํ•œ SW ๊ฒฝ์ง„๋Œ€ํšŒ ๋Œ€๋น„", Course.RegisterStudentType.HIGH_STUDENT, 5);
        Course<UnivStudent> univStudentCourse = new Course<>("OOP ํ”„๋กœ๊ทธ๋ž˜๋ฐ", Course.RegisterStudentType.UNIV_STUDENT, 5);
        Course<Animal> animalCourse = new Course<>("๋ฐ˜๋ ค๋™๋ฌผ ์‚ฌํšŒ์„ฑ ๊ธฐ๋ฅด๊ธฐ", Course.RegisterStudentType.ANIMAL, 5);


        Person person = new Person();
        personCourse.add(person);
//        studentCourse.add(person); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        workerCourse.add(person); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        highStudentCourse.add(person); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        univStudentCourse.add(person); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        animalCourse.add(person); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        System.out.println();

        Student student = new Student();
        personCourse.add(student);
        studentCourse.add(student);
//        workerCourse.add(student); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        highStudentCourse.add(student); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        univStudentCourse.add(student); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        animalCourse.add(student); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        System.out.println();


        Worker worker = new Worker();
        personCourse.add(worker);
//        studentCourse.add(worker); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        workerCourse.add(worker);
//        highStudentCourse.add(worker); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        univStudentCourse.add(worker); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        animalCourse.add(worker); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        System.out.println();


        HighStudent highStudent = new HighStudent();
        personCourse.add(highStudent);
        studentCourse.add(highStudent);
//        workerCourse.add(highStudent); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        highStudentCourse.add(highStudent);
//        univStudentCourse.add(highStudent); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        animalCourse.add(highStudent); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        System.out.println();


        UnivStudent univStudent = new UnivStudent();
        personCourse.add(univStudent);
        studentCourse.add(univStudent);
//        workerCourse.add(univStudent); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        highStudentCourse.add(univStudent); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        univStudentCourse.add(univStudent);
//        animalCourse.add(univStudent); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        System.out.println();

        Animal animal = new Animal();
//        personCourse.add(animal); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        studentCourse.add(animal); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        workerCourse.add(animal); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        highStudentCourse.add(animal); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        univStudentCourse.add(animal); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        animalCourse.add(animal);

        System.out.println("\n\n========================================================= " +
                "register person course results =========================================================");
        CourseUtils.registerPersonCourse(personCourse);
        CourseUtils.registerPersonCourse(studentCourse);
        CourseUtils.registerPersonCourse(workerCourse);
        CourseUtils.registerPersonCourse(highStudentCourse);
        CourseUtils.registerPersonCourse(univStudentCourse);
//        CourseUtils.registerPersonCourse(animalCourse); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.

        System.out.println("\n\n========================================================= " +
                "register animal course results =========================================================");
//        CourseUtils.registerAnimalCourse(personCourse); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        CourseUtils.registerAnimalCourse(studentCourse); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        CourseUtils.registerAnimalCourse(workerCourse); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        CourseUtils.registerAnimalCourse(highStudentCourse); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
//        CourseUtils.registerAnimalCourse(univStudentCourse); // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜.
        CourseUtils.registerAnimalCourse(animalCourse);

    }
}

 

  • ์ œ๋„ˆ๋ฆญ ํƒ€์ž… ์ƒ์†
    • ์ƒ์† ํ›„ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ
    ChildProduct<T, M, C> extends Product<T, M>

์˜ˆ์‹œ

import java.util.Objects;

public class Product<T, M> {
    private T kind;
    private M model;

    public Product() {
    }

    public Product(T kind, M model) {
        this.kind = kind;
        this.model = model;
    }

    public T getKind() {
        return kind;
    }

    public void setKind(T kind) {
        this.kind = kind;
    }

    public M getModel() {
        return model;
    }

    public void setModel(M model) {
        this.model = model;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Product<?, ?> product = (Product<?, ?>) o;
        return kind.equals(product.kind) && model.equals(product.model);
    }

    @Override
    public int hashCode() {
        return Objects.hash(kind, model);
    }

    @Override
    public String toString() {
        return "Product{" +
                "kind=" + kind +
                ", model=" + model +
                '}';
    }
}
import java.util.Objects;

public class ChildProduct<T, M, C> extends Product<T, M> {
    private C company;

    public ChildProduct() {
    }

    public ChildProduct(C company) {
        this.company = company;
    }

    public ChildProduct(T kind, M model, C company) {
        super(kind, model);
        this.company = company;
    }

    public C getCompany() {
        return company;
    }

    public void setCompany(C company) {
        this.company = company;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        ChildProduct<?, ?, ?> that = (ChildProduct<?, ?, ?>) o;
        return company.equals(that.company);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), company);
    }

    @Override
    public String toString() {
        return "ChildProduct{" + super.toString() + ", " +
                "company=" + company +
                '}';
    }
}

 

  • ์ œ๋„ˆ๋ฆญ ํƒ€์ž… ๊ตฌํ˜„
    • ๊ตฌํ˜„ ํ›„ ํƒ€์ž… ์ œํ•œ ๊ฐ€๋Šฅ
    StorageImpl<T extends Clothes> implements Storage<T>
public interface Storage<T> {
    void add(T item);
    T get(int index);
    void remove(T item);
}
import java.util.Arrays;
import java.util.Objects;

public class StorageImpl<T extends Clothes> implements Storage<T> {
    private static final int DEFULAT_SIZE = 10;
    private int size;

    private T[] list;
    private int count;

    public StorageImpl() {
        list = (T[]) new Clothes[DEFULAT_SIZE];
        this.size = DEFULAT_SIZE;
    }

    public StorageImpl(int size) {
        list = (T[]) new Clothes[size];
        this.size = size;
    }

    public T get(int i) {
        return list[i];
    }

    public void add(T element) {
        if (count < size) {
            list[count] = element;
            count++;
        } else {
            T[] origin = Arrays.copyOf(list, count);
            size *= 2;
            list = Arrays.copyOf(origin, size);
            add(element);
        }
    }

    public void remove(T element) {
        int elementIndex = -1;
        for (int i = 0; i < count; i++) {
            if (list[i] != null) {
                if (list[i].equals(element)) {
                    elementIndex = i;
                }
            }
        }
        if (elementIndex == -1) {
            System.out.println(element + " can't be found.");
        } else {
            list[elementIndex] = null;
            for (int i = elementIndex+1; i < count; i++) {
                list[i-1] = list[i];
            }
            count--;

            System.out.println(element + " removed successfully.");
        }
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public T[] getList() {
        return list;
    }

    public void setList(T[] list) {
        this.list = list;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        StorageImpl<?> storage = (StorageImpl<?>) o;
        return size == storage.size && count == storage.count && Arrays.equals(list, storage.list);
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(size, count);
        result = 31 * result + Arrays.hashCode(list);
        return result;
    }

    @Override
    public String toString() {
        return "StorageImpl{" +
                "size=" + size +
                ", list=" + Arrays.toString(list) +
                ", count=" + count +
                '}';
    }
}
import java.util.Objects;

class Clothes {
    private String type;
    private String season;
    private String color;

    public Clothes() {
    }

    public Clothes(String type, String season, String color) {
        this.type = type;
        this.season = season;
        this.color = color;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Clothes clothes = (Clothes) o;
        return type.equals(clothes.type) && season.equals(clothes.season) && color.equals(clothes.color);
    }

    @Override
    public int hashCode() {
        return Objects.hash(type, season, color);
    }

    @Override
    public String toString() {
        return "Clothes{" +
                "type='" + type + '\'' +
                ", season='" + season + '\'' +
                ", color='" + color + '\'' +
                '}';
    }
}

public class ImplementExample {
    public static void main(String[] args) {
        StorageImpl<Clothes> storage = new StorageImpl<>();
        storage.add(new Clothes("์…”์ธ ", "๊ฐ€์„", "๋ธ”๋ฃจ"));
        storage.add(new Clothes("๋ฐ˜๋ฐ”์ง€", "์—ฌ๋ฆ„", "๊ฒ€์ •"));
        storage.add(new Clothes("๋‹ˆํŠธ", "๊ฒจ์šธ", "๋ฒ ์ด์ง€"));
        System.out.println();

        for (int i = 0; i < storage.getCount(); i++) {
            System.out.println("storage.get(i) = " + storage.get(i));
        }

        System.out.println();
        storage.remove(new Clothes("์…”์ธ ", "๊ฐ€์„", "๋ธ”๋ฃจ"));
        storage.remove(new Clothes("๋ฐ˜๋ฐ”์ง€", "์—ฌ๋ฆ„", "๊ฒ€์ •"));
        storage.remove(new Clothes("๋‹ˆํŠธ", "๊ฒจ์šธ", "๋ฒ ์ด์ง€"));
    }
}