Amenable
Amenable's Blog
Amenable
  • λΆ„λ₯˜ 전체보기 (189)
    • πŸ“‚ JAVA (87)
      • μ΄νŽ™ν‹°λΈŒ μžλ°” (65)
      • μ£Όμš” κ°œλ… (22)
    • πŸ“‚ 개발 μ„œμ  (22)
      • μ‹€μš©μ£Όμ˜ ν”„λ‘œκ·Έλž˜λ¨Έ (1)
      • 객체지ν–₯의 사싀과 μ˜€ν•΄ (2)
      • 클린 μ½”λ“œ (8)
      • ν•¨κ»˜ 자라기 (1)
      • 그림으둜 λ°°μš°λŠ” HTTP&Network Basic (10)
    • πŸ“‚ λ°μ΄ν„°λ² μ΄μŠ€ (8)
      • κ°œλ… (8)
      • λ¬Έμ œν’€μ΄ (0)
    • πŸ“‚ λ„€νŠΈμ›Œν¬ (14)
      • κ°œλ… (6)
      • 성곡과 μ‹€νŒ¨λ₯Ό κ²°μ •ν•˜λŠ” 1%의 λ„€νŠΈμ›Œν¬ 원리 (8)
    • πŸ“‚ μŠ€ν”„λ§ (13)
      • κΈ°λ³Έ κ°œλ… (13)
    • πŸ“‚ WEB (5)
    • πŸ“‚ 자료ꡬ쑰 (12)
      • κ°œλ… (2)
      • μ •λ ¬ (8)
      • 트리 (2)
    • πŸ“‚ μ•Œκ³ λ¦¬μ¦˜ (10)
      • μ΅œμ†Œμ‹ μž₯트리 (2)
      • μ΅œλ‹¨ 경둜 (2)
      • λ¬Έμžμ—΄ (2)
      • ETC (4)
    • πŸ“‚ μ•Œκ³ λ¦¬μ¦˜_λ¬Έμ œν’€μ΄ (4)
      • BOJ_λ°±μ€€ (4)
    • πŸ“‚ ν”„λ‘œκ·Έλž˜λ° (3)
    • πŸ“‚ DevOps (2)
      • 배포 (2)
    • πŸ“‚ ν›„κΈ° (8)
      • μš°μ•„ν•œ ν…Œν¬μ½”μŠ€(ν”„λ¦¬μ½”μŠ€) (4)
      • 2023λ…„ (3)
      • 2024λ…„ (1)
    • πŸ“‚ 회고 (1)
      • 2023λ…„ (1)

λΈ”λ‘œκ·Έ 메뉴

  • πŸš€ GitHub

ν‹°μŠ€ν† λ¦¬

hELLO Β· Designed By μ •μƒμš°.
Amenable
πŸ“‚ JAVA/μ£Όμš” κ°œλ…

μ œλ„€λ¦­(Generics) - κΈ°λ³Έ κ°œλ…

μ œλ„€λ¦­(Generics) - κΈ°λ³Έ κ°œλ…
πŸ“‚ JAVA/μ£Όμš” κ°œλ…

μ œλ„€λ¦­(Generics) - κΈ°λ³Έ κ°œλ…

2023. 5. 13. 00:22

  JDK 1.5λΆ€ν„° λ„μž…λœ μ œλ„€λ¦­(Generics)에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μž.

  'μ œλ„€λ¦­(Generic)을 μ‚¬μš©ν•˜λ©΄ λ‹€μ–‘ν•œ νƒ€μž…μ„ μ‚¬μš©ν•  수 μžˆλ‹€.' μ •λ„λ‘œλ§Œ μ•Œκ³  μžˆμ—ˆλŠ”λ° μ œλŒ€λ‘œ κ³΅λΆ€ν•˜λ €κ³  λ³΄λ‹ˆκΉ 생각보닀 양이 λ§Žλ‹€. 쫌 많이 λ§Žλ‹€...

  κ·Έλž˜μ„œ 이번 κΈ€μ—μ„œλŠ” μ œλ„€λ¦­μ˜ 기번 κ°œλ…μ— λŒ€ν•΄μ„œ μ•Œμ•„λ³΄κ³  λ‹€μŒ 글듀을 톡해 더 ꡬ체적으둜 μ•Œμ•„λ³΄λŠ” κ²ƒμœΌλ‘œ ν•˜μž. (μ΄νŽ™ν‹°λΈŒ μžλ°” 5μž₯의 μ œλ„€λ¦­(μ•„μ΄ν…œ 26 ~ μ•„μ΄ν…œ 33) λ‚΄μš©κ³Ό μ™€μΌλ“œμΉ΄λ“œ λ“±μ˜ λ‚΄μš©μ„ μΆ”κ°€μ μœΌλ‘œ λ‹€λ£° μ˜ˆμ •μ΄λ‹€.) 

(μ΄νŽ™ν‹°λΈŒ μžλ°” 5μž₯ μ œλ„€λ¦­ νŒŒνŠΈλ₯Ό μ½μœΌλ €λŠ”λ° μ΄ν•΄κ°€ μž˜ λ˜μ§€ μ•Šμ•„μ„œ μ œλ„€λ¦­μ˜ κΈ°λ³ΈλΆ€ν„° λΈ”λ‘œκΉ…ν•˜κ³  μžˆλŠ” 쀑이닀...πŸ˜…)

 

1. μ œλ„€λ¦­(Generic) κ°œλ… 🧱

  μš°λ¦¬λŠ” μ œλ„€λ¦­(Generics)을 κ·Έ μ–΄λ– ν•œ κ°œλ…λ³΄λ‹€ 자주 μ‚¬μš©ν•œλ‹€.

public static void main(String[] args) {
    ArrayList<Integer> numbers = new ArrayList<Integer>();
    ArrayList<String> names = new ArrayList<String>();
}

// ArrayList.java
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

  ArrayList의 κΊΎμ‡ κ΄„ν˜Έ(< >)μ•ˆμ— 클래슀 λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•  데이터 νƒ€μž…(Integer, String,..)을 μ§€μ •ν•΄ μ£Όμ—ˆλ‹€. 이것이 μ œλ„€λ¦­μ„ μ‚¬μš©ν•œ 것이닀.

 

  μ œλ„€λ¦­μ€ 클래슀 λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•  데이터 νƒ€μž…μ„ μ™ΈλΆ€μ—μ„œ μ§€μ •ν•˜λŠ” 기법을 μ˜λ―Έν•œλ‹€.

  μ œλ„€λ¦­μ€ λ‹€μ–‘ν•œ νƒ€μž…μ˜ 객체듀을 λ‹€λ£¨λŠ” λ©”μ„œλ“œλ‚˜ μ»¬λ ‰μ…˜ ν΄λž˜μŠ€μ— 컴파일 μ‹œμ˜ νƒ€μž… 체크(compile-time type check)λ₯Ό ν•΄μ£ΌλŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€. 객체의 νƒ€μž…을 μ»΄νŒŒμΌ μ‹œμ— μ²΄ν¬ν•˜κΈ° λ•Œλ¬Έμ— κ°μ²΄μ˜ νƒ€μž… μ•ˆμ „성을 λ†’이고 ν˜•λ³€ν™˜μ˜ λ²ˆκ±°λ‘œμ›€μ΄ μ€„μ–΄λ“ λ‹€.

public static void main(String[] args) {

    ArrayList<Integer> nums = new ArrayList<>();

    // 1. νƒ€μž…μ˜ μ•ˆμ •μ„±μ„ 제곡
    nums.add(1);
    // nums.add("1"); // 컴파일 μ—λŸ¬

    // 2. ν˜•λ³€ν™˜μ˜ λ²ˆκ±°λ‘œμ›€μ΄ 쀄어듬
    Integer num = nums.get(0);
    // Integer num1 = (Integer) nums.get(0);
}

 

πŸ“Œ μ œλ„€λ¦­μ˜ μž₯점

  1. νƒ€μž… μ•ˆμ •성을 μ œκ³΅
  2. νƒ€μž…μ²΄ν¬μ™€ ν˜•λ³€ν™˜μ„ μƒλž΅ν•  수 μžˆμœΌλ―€λ‘œ μ½”λ“œκ°€ κ°„κ²°ν•΄μ§„λ‹€.

 

2. μ œλ„€λ¦­ 클래슀 πŸ”¨

  μ œλ„€λ¦­ νƒ€μž…μ€ ν΄λž˜μŠ€μ™€ λ©”μ„œλ“œμ— μ„ μ–Έν•  수 μžˆλ‹€. λ¨Όμ € ν΄λž˜μŠ€μ— μ„ μ–Έν•˜λŠ” μ œλ„€λ¦­ νƒ€μž…μ— λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μž.

πŸ“™ 1. μ œλ„€λ¦­ 클래슀 μ„ μ–Έ

  λ‹€μŒκ³Ό 같이 κΈ°μ‘΄ 클래슀 μ˜†μ— '<T>'λ₯Ό λΆ™μ—¬μ„œ μ œλ„€λ¦­ 클래슀λ₯Ό λ§Œλ“€ 수 μžˆλ‹€.

// κΈ°μ‘΄μ½”λ“œ
// μ œλ„€λ¦­ 클래슀 X
public class Box {
    Object item;

    void setItem(Object item) {
        this.item = item;
    }
    Object getItem() {
        return item;
    }
}

// μ œλ„€λ¦­ 클래슀 O
public class Box<T> {
    T item;

    void setItem(T item) {
        this.item = item;
    }
    T getItem() {
        return item;
    }
}

  μ—¬κΈ°μ„œ TλŠ” νƒ€μž… λ³€μˆ˜(Type Variable)라고 ν•œλ‹€. κΌ­ Tλ§Œμ„ 써야 ν•˜λŠ” 게 μ•„λ‹ˆλΌ E, K, V, N,... λ“± λ‹€λ₯Έ 기호λ₯Ό μ‚¬μš©ν•΄λ„ λœλ‹€.  기호의 μ’…λ₯˜λ“€λ§Œ λ‹€λ₯Ό λΏ 'μž„μ˜μ˜ μ°Έμ‘°ν˜• νƒ€μž…'μ΄λΌλŠ” κ²ƒμ„ μ˜λ―Έν•œλ‹€λŠ” κ²ƒμ€ λͺ¨λ‘ κ°™λ‹€. 

  ν•˜μ§€λ§Œ μ•„λž˜μ™€ 같이 암묡적인 κ·œμΉ™μ΄ μ‘΄μž¬ν•˜λ―€λ‘œ 상황에 맞게 μ˜λ―Έν•˜λŠ” 문자λ₯Ό μ„ νƒν•΄μ„œ μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€.

νƒ€μž… μ„€λͺ…
T νƒ€μž…(Type)
E μš”μ†Œ(Element)
ex. ArrayList<E>
K ν‚€(Key)
ex. Map<K, V>
V κ°’(Value)

  μ œλ„€λ¦­ 클래슀λ₯Ό μ΄μš©ν•˜μ—¬ 객체λ₯Ό 생성할 λ•ŒλŠ” μ°Έμ‘°λ³€μˆ˜μ™€ μƒμ„±μžμ— νƒ€μž… T λŒ€μ‹ μ— μ‚¬μš©λ  μ‹€μ œ νƒ€μž…μ„ μ§€μ •ν•΄ μ£Όλ©΄ λœλ‹€.

public static void main(String[] args) {
    
    // νƒ€μž… λ³€μˆ˜λ‘œ String을 μ‚¬μš©ν•œ 경우
    Box<String> boxString = new Box<String>();
    boxString.setItem("boxString");
    String findBoxStringItem = boxString.getItem();

    // νƒ€μž… λ³€μˆ˜λ‘œ Integerλ₯Ό μ‚¬μš©ν•œ 경우
    Box<Integer> boxInteger = new Box<Integer>();
    boxInteger.setItem(123);
    Integer findBoxIntegerItem = boxInteger.getItem();
}

  μ œλ„€λ¦­μ΄ λ„μž…λ˜κΈ° μ΄μ „μ˜ μ½”λ“œμ™€ ν˜Έν™˜μ„ μœ„ν•΄, μ œλ„€λ¦­ ν΄λž˜μŠ€μΈλ°λ„ λ‹€μŒκ³Ό 같이 μ˜ˆμ „μ˜ λ°©μ‹μœΌλ‘œ 객체λ₯Ό μƒμ„±ν•˜λŠ” 것이 ν—ˆμš©λœλ‹€.

public static void main(String[] args) {

    // μ˜ˆμ „μ˜ λ°©μ‹μœΌλ‘œ 객체λ₯Ό 생성
    Box boxPast = new Box();
    boxPast.setItem("123");
    Object findBoxPastItem = boxPast.getItem();
}

  ν•˜μ§€λ§Œ, ν•΄λ‹Ή 방법은 단지 μ œλ„€λ¦­μ΄ λ„μž…λ˜κΈ° μ΄μ „μ˜ μ½”λ“œμ™€ ν˜Έν™˜μ„±μ„ μœ„ν•œ κ²ƒμ΄λ―€λ‘œ ν•΄λ‹Ή λ°©λ²•μ˜ μ‚¬μš©μ€ μ§€μ–‘ν•˜λ„λ‘ ν•˜μž.

πŸ“™ 2. μ œλ„€λ¦­ μš©μ–΄

  μ œλ„€λ¦­μ— λŒ€ν•΄μ„œ μ–΄λŠ 정도 감이 μž‘ν˜”κ³  더 λ§Žμ€ κ°œλ…μ„ μ•ŒκΈ° μœ„ν•΄ μ§€κΈˆ 타이밍에 μ œλ„€λ¦­μ˜ μš©μ–΄λ₯Ό ν•œλ²ˆ 짚고 λ„˜μ–΄κ°€μž. μš©μ–΄λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

  • Box<T>
    μ œλ„€λ¦­ ν΄λž˜μŠ€
    'T의 Box' λ˜λŠ” 'T Box'라고 μ½λŠ”λ‹€.
  • T
    νƒ€μž… λ³€μˆ˜ λ˜λŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜(TλŠ” νƒ€μž…λ¬Έμž)
  • Box
    μ›μ‹œ νƒ€μž…(Raw Type)

  • μ œλ„€λ¦­ νƒ€μž… ν˜ΈμΆœ
    νƒ€μž… λ§€κ°œλ³€μˆ˜(T)에 νƒ€μž…을 μ§€μ •ν•˜λŠ” κ²ƒ
  • λ§€κ°œλ³€μˆ˜ν™”λœ νƒ€μž…(Parameterized Type)
    μ§€μ •λœ νƒ€μž…(μœ„μ˜ κ·Έλ¦Όμ—μ„œλŠ” String)
    μš©μ–΄κ°€ μ’€ κΈΈκΈ° λ•Œλ¬Έμ— μ΄λ²ˆ κΈ€μ—μ„œλŠ” 'λŒ€μž…λœ νƒ€μž…'이라고 μ‚¬μš©ν•˜μž.

πŸ“™ 3. μ œλ„€λ¦­ μ œν•œ

  μ œλ„€λ¦­ ν΄λž˜μŠ€λŠ” λ‹€μŒκ³Ό 같은 2κ°€μ§€ μƒν™©μ—μ„œ μ‚¬μš©ν•  수 μ—†λ‹€.

πŸ“Œ 1. static멀버에 νƒ€μž… λ³€μˆ˜ Tλ₯Ό μ‚¬μš©ν•  μˆ˜ μ—†λ‹€.

  staticλ©€λ²„λŠ” λͺ¨λ“  객체에 λŒ€ν•΄ λ™μΌν•˜κ²Œ λ™μž‘ν•΄μ•Ό ν•œλ‹€. 

  TλŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λ‘œ κ°„μ£Όλ˜κ³ , static λ©€λ²„λŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  수 μ—†μœΌλ―€λ‘œ static 멀버에 νƒ€μž… λ³€μˆ˜ Tλ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€.

class Box<T> {
    static T item; // μ—λŸ¬
    static int compare(T t1, T t2) {}; // μ—λŸ¬
}

πŸ“Œ 2. μ œλ„€λ¦­ νƒ€μž…μ˜ λ°°μ—΄μ„ μƒμ„±ν•  μˆ˜ μ—†λ‹€.

  μ œλ„€λ¦­ λ°°μ—΄ νƒ€μž…μ˜ μ°Έμ‘°λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 것은 κ°€λŠ₯ν•˜μ§€λ§Œ, 'new T[100]'κ³Ό 같이 배열을 μƒμ„±ν•˜λŠ” 것은 μ•ˆ λœλ‹€.

class Box<T> {

    // Tνƒ€μž…μ˜ 배열을 μœ„ν•œ μ°Έμ‘° λ³€μˆ˜
    T[] itemArr; // OK

    T[] toArray() {
        // μ œλ„€λ¦­ νƒ€μž…μ˜ λ°°μ—΄ 생성
        T[] tmpArr = new T[itemArr.length]; // μ—λŸ¬

        return tmpArr;
    }
}

  μ œλ„€λ¦­ 배열을 생성할 수 μ—†λŠ” 것은 newμ—°μ‚°μž λ•Œλ¬Έμ΄λ‹€. new μ—°μ‚°μžλŠ” μ»΄νŒŒμΌ μ‹œμ μ— νƒ€μž… Tκ°€ λ¬΄μ—‡μΈμ§€ μ •ν™•νžˆ μ•Œμ•„μ•Ό ν•œλ‹€.

  ν•˜μ§€λ§Œ μœ„μ˜ μ½”λ“œμ—μ„œ Box<T>클래슀λ₯Ό μ»΄νŒŒμΌν•˜λŠ” μ‹œμ μ— Tκ°€ μ–΄λ–€ νƒ€μž…μ΄ 될지 μ „ν˜€ μ•Œ 수 μ—†λ‹€. 

πŸ“™ 4. μ œλ„€λ¦­ 클래슀의 객체 생성과 μ‚¬μš©

  Box<T>κ°€ λ‹€μŒκ³Ό 같이 μ •μ˜λ˜μ–΄ μžˆλ‹€κ³  ν•˜μž.

class Box<T> {
    ArrayList<T> list = new ArrayList<T>();

    void add(T item) {
        list.add(item);
    }

    T get(int i){
        return list.get(i);
    }

    ArrayList<T> getList() {
        return list;
    }

    int size() {
        return list.size();
    }

    public String toString() {
        return list.toString();
    }
}

  μ œλ„€λ¦­ 클래슀의 객체λ₯Ό μƒμ„±ν•˜κ³  μ‚¬μš©ν•  λ•Œ λ‹€μŒμ˜ κ·œμΉ™μ„ μ£Όμ˜ν•΄μ„œ 생성 및 μ‚¬μš©μ„ ν•˜λ©΄ λœλ‹€. (Apple이 Fruit의 μžμ†μ΄λΌκ³  κ°€μ •ν•œλ‹€.)

πŸ“Œ 1. μ°Έμ‘°λ³€μˆ˜μ™€ μƒμ„±μžμ— λŒ€μž…λœ νƒ€μž…(λ§€κ°œλ³€μˆ˜ν™”λœ νƒ€μž…)은 μΌμΉ˜ν•΄μ•Ό ν•œλ‹€.

public static void main(String[] args) {

    // OK
    Box<Apple> appleBox = new Box<Apple>();
    // μ—λŸ¬
    Box<Apple> appleBox = new Box<Grape>();
}

πŸ“Œ 2. μΆ”정이 κ°€λŠ₯ν•œ νƒ€μž… μƒλž΅ κ°€λŠ₯(JDK 1.7λΆ€ν„°)

public static void main(String[] args) {

    // OK
    Box<Apple> appleBox = new Box<Apple>();
    // OK // μƒλž΅ κ°€λŠ₯
    Box<Apple> appleBox = new Box<>();
}

πŸ“Œ 3. λ‹€ν˜•성을 μ‚¬μš©ν•˜λŠ” κ²½μš°

public static void main(String[] args) {

    // μ˜ˆμ‹œ 1
    Box<Apple> appleBox = new FruitBox<Apple>();
    // μ˜ˆμ‹œ 2
    Box<Fruit> fruitBox = new Box<Fruit>();
    fruitBox.add(new Fruit());
    fruitBox.add(new Apple());
}

πŸ“™ 5. μ œν•œλœ μ œλ„€λ¦­ 클래슀

  λͺ¨λ“  μ’…λ₯˜μ˜ νƒ€μž…μ„ μ΄μš©ν•˜μ—¬ νƒ€μž… 문자λ₯Ό μ§€μ •ν•  수 μžˆλ‹€.

  λͺ¨λ“  μ’…λ₯˜μ˜ νƒ€μž…μœΌλ‘œ νƒ€μž… 문자λ₯Ό μ§€μ •ν•  수 μžˆλŠ” 것이 μ•„λ‹Œ, μ œν•œλœ νƒ€μž…μ˜ μ’…λ₯˜λ‘œ νƒ€μž… 문자λ₯Ό μ§€μ •ν•  수 μžˆλ„λ‘ ν•˜λŠ” 방법을 μ•Œμ•„λ³΄λ„λ‘ ν•˜μž.

  'extends'λ₯Ό μ‚¬μš©ν•˜λ©΄ νŠΉμ • νƒ€μž…κ³Ό νŠΉμ • νƒ€μž…μ˜ μžμ†λ“€λ§Œ λŒ€μž…ν•  수 μžˆλ„λ‘ μ œν•œν•  수 μžˆλ‹€.

public class Fruit {
}

public class Apple extends Fruit{
}

public class FruitBox<T extends Fruit> {
    ArrayList<T> list = new ArrayList<>();
}

public static void main(String[] args) {
    FruitBox<Fruit> fruitBox = new FruitBox<>();
    FruitBox<Apple> appleBox = new FruitBox<>();
}

  μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€λŠ” μ œμ•½μ΄ ν•„μš”ν•˜λ‹€λ©΄ μ•„λž˜μ™€ 같이 μ‚¬μš©ν•  수 μžˆλ‹€. (implementsκ°€ μ•„λ‹ˆλΌ extendsλΌλŠ” 점을 μ£Όμ˜ν•˜μž.)

interface Eatable {}
class FruitBox<T extends Eatable> { ... }

  Fruit의 μžμ†μ΄λ©΄μ„œ Eatable μΈν„°νŽ˜μ΄μŠ€λ„ κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€λ©΄ '&'λ₯Ό μ΄μš©ν•˜μ—¬ ν‘œν˜„ν•  수 μžˆλ‹€.

class FruitBox<T extends Fruit & Eatable> { ... }

 

3. μ™€μΌλ“œμΉ΄λ“œ πŸ”§

  λ§€κ°œλ³€μˆ˜μ— κ³ΌμΌλ°•μŠ€(FruitBox)λ₯Ό λŒ€μž…ν•˜λ©΄ 주슀(Juice)λ₯Ό λ§Œλ“€μ–΄μ„œ λ°˜ν™˜ν•˜λŠ” JuicerλΌλŠ” ν΄λž˜μŠ€κ°€ 있고, 이 ν΄λž˜μŠ€μ— 과일을 주슀둜 λ§Œλ“€μ–΄μ„œ λ°˜ν™˜ν•˜λŠ” makeJuice()λΌλŠ” static λ©”μ„œλ“œκ°€ μžˆλ‹€κ³  ν•˜μž.

public class Juicer {
    static Juice makeJuice(FruitBox<Fruit> box) {
        String tmp = "";
        for(Fruit f : box.getList())
            tmp += f + " ";
        return new Juice(tmp);
    }
}

  λ§€κ°œλ³€μˆ˜λ‘œ Fruit만 μ‚¬μš©ν•˜λŠ” 것이 μ•„λ‹Œ λ‹€μ–‘ν•œ νƒ€μž…μ„ μ‚¬μš©ν•  수 μžˆλ„λ‘ μ œλ„€λ¦­μ„ μ΄μš©ν•˜λ €κ³  ν•œλ‹€. ν•˜μ§€λ§Œ μ•„λž˜μ™€ 같은 λ¬Έμ œκ°€ μžˆλ‹€.

  1. Juicer ν΄λž˜μŠ€λŠ” μ œλ„€λ¦­ ν΄λž˜μŠ€κ°€ μ•„λ‹ˆλ‹€.
  2. Juicer ν΄λž˜μŠ€κ°€ μ œλ„€λ¦­ ν΄λž˜μŠ€λΌκ³  ν•΄λ„, static λ©”μ„œλ“œμ—λŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜ Tλ₯Ό λ§€κ°œλ³€μˆ˜μ— μ‚¬μš©ν•  μˆ˜ μ—†λ‹€.

 

  κ·Έλž˜μ„œ μ–΄μ©” 수 없이 μ•„λž˜μ™€ 같이 μ—¬λŸ¬ κ°€μ§€ νƒ€μž…μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό κ°–λŠ” makeJuice()λ₯Ό λ§Œλ“€μ—ˆλ‹€κ³  ν•˜μž.

// λ©”μ„œλ“œ 쀑볡 μ •μ˜
public class Juicer {
    static Juice makeJuice(FruitBox<Fruit> box) {
        String tmp = "";
        for(Fruit f : box.getList())
            tmp += f + " ";
        return new Juice(tmp);
    }
    
    static Juice makeJuice(FruitBox<Apple> box) {
        String tmp = "";
        for(Fruit f : box.getList())
            tmp += f + " ";
        return new Juice(tmp);
    }
}

  μ΄λ ‡κ²Œ μ˜€λ²„λ‘œλ”©μ„ ν•˜λ©΄ 컴파일 μ—λŸ¬κ°€ λ‚œλ‹€. μ œλ„€λ¦­ νƒ€μž…μ΄ λ‹€λ₯΄λ‹€λŠ” κ²ƒλ§ŒμœΌλ‘œλŠ” μ˜€λ²„λ‘œλ”©μ΄ μ„±λ¦½ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€. μ œλ„€λ¦­ νƒ€μž…은 μ»΄νŒŒμΌλŸ¬κ°€ μ»΄νŒŒμΌν•  λ•Œλ§Œ μ‚¬μš©ν•˜κ³  μ œκ±°ν•˜κΈ° λ•Œλ¬Έμ— μœ„μ˜ λ‘ λ©”μ„œλ“œλŠ” μ˜€λ²„λ‘œλ”©μ΄ μ•„λ‹ˆλΌ 'λ©”μ„œλ“œ μ€‘볡 μ •μ˜'이닀.

 

  이런 κ²½μš°μ— μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œ λ§Œλ“€μ–΄μ§„ 것이 'μ™€μΌλ“œμΉ΄λ“œ'이닀. κΈ°ν˜ΈλŠ” '?'이고, μ™€μΌλ“œμΉ΄λ“œλŠ” μ–΄λ– ν•œ νƒ€μž…λ„ κ°€λŠ₯ν•˜λ‹€.

  ν•˜μ§€λ§Œ '?'μœΌλ‘œλŠ”  Object νƒ€μž…κ³Ό λ‹€λ₯Ό 게 μ—†μœΌλ―€λ‘œ 일반적으둜 'extends'와 'super'λ₯Ό μ΄μš©ν•˜μ—¬ μƒν™˜(upper bound)κ³Ό ν•˜ν•œ(lower bound)을 λ‘λ©΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

  μ™€μΌλ“œμΉ΄λ“œμ—μ„œμ˜ κ·œμΉ™μ€ μ•„λž˜μ™€ κ°™λ‹€.

  • <?>
    νƒ€μž… μ œν•œ μ—†μŒ
    λͺ¨λ“  νƒ€μž…이 κ°€λŠ₯
    <? extends Object>와 λ™μΌ
  • <? extends T>
    μ™€μΌλ“œμΉ΄λ“œμ˜ μƒν•œ μ œν•œ
    T와 κ·Έ μžμ†λ“€λ§Œ κ°€λŠ₯
  • <? super T>
    μ™€μΌλ“œμΉ΄λ“œμ˜ ν•˜ν•œ μ œν•œ
    T와 κ·Έ μ‘°μƒλ“€λ§Œ κ°€λŠ₯

πŸ“™ 1. <? extends T>

  λ¨Όμ € 'extends'λ₯Ό μ‚¬μš©ν•˜λŠ” 경우λ₯Ό μ‚΄νŽ΄λ³΄μž. Juicer ν΄λž˜μŠ€μ— extendsλ₯Ό μ‚¬μš©ν•˜λ©΄ λ¬Έμ œμ˜ μƒν™©μ„ ν•΄κ²°ν•  μˆ˜ μžˆλ‹€.

public class Juicer {

    static Juice makeJuice(FruitBox<? extends Fruit> box) {
        String tmp = "";
        for(Fruit f : box.getList())
            tmp += f + " ";
        return new Juice(tmp);
    }
}

public static void main(String[] args) {
    FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();
    FruitBox<Apple> appleBox = new FruitBox<Apple>();

    System.out.println(Juicer.makeJuice(fruitBox));
    System.out.println(Juicer.makeJuice(appleBox));
}

πŸ“™ 2. <? super T>

  'super'λ₯Ό μ‚¬μš©ν•œ κ²½μš°λ„ μ‚΄νŽ΄λ³΄μž. Fruitκ°€ μžˆκ³  μžμ† ν΄λž˜μŠ€λ‘œ Appleκ³Ό Grapeκ°€ μžˆλ‹€κ³  ν•˜μž.

public class Fruit {
    String name;
    int weight;

    public Fruit(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }
}

public class Apple extends Fruit{
    public Apple(String name, int weight) {
        super(name, weight);
    }
}

public class Grape extends Fruit{
    public Grape(String name, int weight) {
        super(name, weight);
    }
}

  Collections.sort()λ₯Ό μ΄μš©ν•΄μ„œ appleBox와 grapeBox에 λ‹΄κΈ΄ 과일을 λ¬΄κ²Œλ³„λ‘œ μ •λ ¬ν•œλ‹€κ³  ν•˜μž. Collections.sort()의 λ©”μ„œλ“œ μ„ μ–ΈλΆ€λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

public static <T> void sort(List<T> list, Comparator<? super T> c)

  첫 번째 λ§€κ°œλ³€μˆ˜λŠ” μ •λ ¬ν•  λŒ€μƒμ΄κ³ , 두 번째 λ§€κ°œλ³€μˆ˜λŠ” μ •λ ¬ν•  방법이 μ •μ˜λœ Comparator이닀.

 

  Collections.sort()κ°€ μ™€μΌλ“œμΉ΄λ“œμ˜ ν•˜ν•œμ œν•œ(<? super T>) μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•˜κ³  μžˆμ§€λ§Œ, 이것을 μ΄μš©ν•˜μ§€ μ•ŠλŠ”λ‹€κ³  κ°€μ •ν•΄ 보자.

  그러면 Collections.sort()λ₯Ό μ‚¬μš©ν•  λ•Œ νƒ€μž…μ„ λͺ…μ‹œν•˜κ³  그에 ν•΄λ‹Ήν•˜λŠ” Comparator만 μ‚¬μš©ν•΄μ•Ό ν•  것이닀.

public class AppleComp implements Comparator<Apple> {

    @Override
    public int compare(Apple o1, Apple o2) {
        return Integer.compare(o1.weight, o2.weight);
    }
}

public class GrapeComp implements Comparator<Grape> {

    @Override
    public int compare(Grape o1, Grape o2) {
        return Integer.compare(o1.weight, o2.weight);
    }
}

public static void main(String[] args) {
    FruitBox<Apple> appleBox = new FruitBox<Apple>();
    FruitBox<Grape> grapeBox = new FruitBox<Grape>();

    appleBox.add(new Apple("GreenApple", 200));
    appleBox.add(new Apple("GreenApple", 100));

    grapeBox.add(new Grape("GreenApple", 200));
    grapeBox.add(new Grape("GreenApple", 100));

    Collections.sort(appleBox.getList(), new AppleComp());
    Collections.sort(grapeBox.getList(), new GrapeComp());
}

  AppleComp와 GrapeCompλŠ” νƒ€μž…λ§Œ λ‹€λ₯Ό 뿐 μ™„μ „νžˆ 같은 μ½”λ“œμ΄λ‹€.

  μ΄λ ‡κ²Œ μ‚¬μš©ν•œλ‹€κ³  ν•˜λ©΄ μ½”λ“œ 쀑볡 문제뿐만 μ•„λ‹ˆλΌ λ§Œμ•½ μƒˆλ‘œμš΄ Fruit의 μžμ†μ΄ 생긴닀면 κ³„μ†ν•΄μ„œ μœ„μ™€ 같은 μ½”λ“œλ₯Ό λ°˜λ³΅ν•΄μ„œ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€λŠ” λ¬Έμ œκ°€ μ‘΄μž¬ν•œλ‹€.

 

  이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ νƒ€μž… 맀개 λ³€μˆ˜μ— ν•˜ν•œ μ œν•œμ˜ μ™€μΌλ“œμΉ΄λ“œ(<? super T>)λ₯Ό ν™œμš©ν•΄μ•Ό ν•œλ‹€.

public class FruitComp implements Comparator<Fruit> {

    @Override
    public int compare(Fruit o1, Fruit o2) {
        return Integer.compare(o1.weight, o2.weight);
    }
}

public static void main(String[] args) {
    FruitBox<Apple> appleBox = new FruitBox<Apple>();
    FruitBox<Grape> grapeBox = new FruitBox<Grape>();

    appleBox.add(new Apple("GreenApple", 200));
    appleBox.add(new Apple("GreenApple", 100));

    grapeBox.add(new Grape("GreenApple", 200));
    grapeBox.add(new Grape("GreenApple", 100));

    Collections.sort(appleBox.getList(), new FruitComp());
    Collections.sort(grapeBox.getList(), new FruitComp());
}

  μ΄λ ‡κ²Œ ν•˜λ©΄ AppleComp와 GrapeCompλ₯Ό λ”°λ‘œ μ‚¬μš©ν•˜λŠ” 것이 μ•„λ‹Œ FruitCompλ§Œμ„ μ΄μš©ν•΄μ„œ 정렬이 κ°€λŠ₯ν•˜λ‹€.

  μ΄λŸ¬ν•œ μž₯점 λ•Œλ¬Έμ— Comparatorμ—λŠ” 항상 <? super T>κ°€ μŠ΅κ΄€μ μœΌλ‘œ λ”°λΌλΆ™κ²Œ λœλ‹€.

 

4. μ œλ„€λ¦­ λ©”μ„œλ“œ πŸ”©

  μ œλ„€λ¦­ νƒ€μž…μ€ ν΄λž˜μŠ€μ™€ λ©”μ„œλ“œμ— μ„ μ–Έν•  수 μžˆλ‹€κ³  ν•˜μ˜€λ‹€. μ§€κΈˆκΉŒμ§€λŠ” ν΄λž˜μŠ€μ— μ„ μ–Έν•˜λŠ” μ œλ„€λ¦­ νƒ€μž…에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μ•˜κ³ , μ΄μ œλΆ€ν„°λŠ” λ©”μ„œλ“œμ— μ„ μ–Έν•˜λŠ” μ œλ„€λ¦­ νƒ€μž…에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μž.

  λ©”μ„œλ“œμ— νƒ€μž… λ³€μˆ˜κ°€ μžˆλ‹€κ³  ν•΄μ„œ 그것이 μ œλ„€λ¦­ λ©”μ„œλ“œλŠ” μ•„λ‹ˆλ‹€.

public class FruitBox<T> {

    // μ œλ„€λ¦­ λ©”μ„œλ“œ X
    // νƒ€μž… λ³€μˆ˜λ‘œ νƒ€μž…μ„ μ§€μ •ν•œ λ©”μ„œλ“œ O
    public T addBox(T item){
        ...
    }
}

  μœ„μ˜ μ½”λ“œλŠ” 단지 νƒ€μž… λ³€μˆ˜λ‘œ νƒ€μž…μ„ μ§€μ •ν•œ λ©”μ„œλ“œλ‹€. μ œλ„€λ¦­ λ©”μ„œλ“œκ°€ μ•„λ‹ˆλ‹€.

 

'μ œλ„€λ¦­ λ©”μ„œλ“œ'λž€ λ©”μ„œλ“œμ˜ μ„ μ–ΈλΆ€μ— μ œλ„€λ¦­ νƒ€μž…이 μ„ μ–Έλœ λ©”μ„œλ“œλ₯Ό λ§ν•œλ‹€. μ¦‰, λ©”μ„œλ“œμ˜ μ„ μ–ΈλΆ€μ— <T>κ°€ μžˆμ–΄μ•Ό ν•œλ‹€.

static <T> void sort (List<T> list, Comparator<? super T> c)

  μ•žμ„œ μ‚΄νŽ΄λ³Έ κ²ƒμ²˜λŸΌ, Collections.sort()κ°€ λ°”λ‘œ μ œλ„€λ¦­ λ©”μ„œλ“œμ΄λ‹€. μ œλ„€λ¦­ νƒ€μž…μ˜ μ„ μ–Έ μœ„μΉ˜λŠ” λ°˜ν™˜ νƒ€μž… λ°”λ‘œ μ•žμ— μœ„μΉ˜ν•œλ‹€.

 

  'μ œλ„€λ¦­ ν΄λž˜μŠ€μ— μ •μ˜λœ νƒ€μž… λ§€κ°œλ³€μˆ˜'와 'μ œλ„€λ¦­ λ©”μ„œλ“œμ— μ •μ˜λœ νƒ€μž… λ§€κ°œλ³€μˆ˜'λŠ” μ „ν˜€ λ³„κ°œμ˜ κ²ƒμ΄λΌλŠ” 것에 μ£Όμ˜ν•˜μž.

public class FruitBox<T> {

    ...
    // 1번 λ©”μ„œλ“œ
    // μ œλ„€λ¦­ λ©”μ„œλ“œ X
    // νƒ€μž… λ³€μˆ˜λ‘œ νƒ€μž…μ„ μ§€μ •ν•œ λ©”μ„œλ“œ O
    // 클래슀의 νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό 받아와 μ‚¬μš©ν•˜λŠ” 일반 λ©”μ„œλ“œ
    public T addBox(T item){
        ...
    }

    // 2번 λ©”μ„œλ“œ
    // μ œλ„€λ¦­ λ©”μ„œλ“œ O
    // λ…λ¦½μ μœΌλ‘œ νƒ€μž… ν• λ‹Ή μš΄μ˜λ˜λŠ” μ œλ„€λ¦­ λ©”μ„œλ“œ
    static <T> void sort(List<T> list, Comparator<? super T> c) {
        ...
    }
}

  1번 λ©”μ„œλ“œλŠ” μ œλ„€λ¦­ λ©”μ„œλ“œκ°€ μ•„λ‹ˆκ³ , 2번 λ©”μ„œλ“œλŠ” μ œλ„€λ¦­ λ©”μ„œλ“œμ΄λ‹€.

각각의 νŠΉμ§•μ€ μ•„λž˜μ™€ κ°™λ‹€.

  • μ œλ„€λ¦­ λ©”μ„œλ“œ X (1번 λ©”μ„œλ“œ)
    클래슀의 μ œλ„€λ¦­ <T>μ—μ„œ μ„€μ •λœ νƒ€μž…을 λ°›μ•„와 λ°˜ν™˜ νƒ€μž…μœΌλ‘œ μ‚¬μš©ν•  λΏμΈ μΌλ°˜ λ©”μ„œλ“œ
  • μ œλ„€λ¦­ λ©”μ„œλ“œ O (2번 λ©”μ„œλ“œ)
    λ©”μ„œλ“œμ— <T> μ œλ„€λ¦­μ„ μ„€μ •ν•¨μœΌλ‘œμ¨ λ™μ μœΌλ‘œ νƒ€μž…을 λ°›μ•„와 μ‚¬μš©ν•  μˆ˜ μžˆλ‹€.
    λ…λ¦½μ μœΌλ‘œ 운용 κ°€λŠ₯ν•˜λ‹€.

 

  μ œλ„€λ¦­ 클래슀 FruitBox에 μ„ μ–Έλœ νƒ€μž… λ§€κ°œλ³€μˆ˜ T와 μ œλ„€λ¦­ λ©”μ„œλ“œ sort()에 μ„ μ–Έλœ νƒ€μž… λ§€κ°œλ³€μˆ˜ TλŠ” νƒ€μž… 문자만 같을 뿐 μ„œλ‘œ λ‹€λ₯Έ 것이닀.

 

  μ œλ„€λ¦­ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ static을 μ΄μš©ν•  수 μžˆλ‹€λŠ” 것에 μ£Όλͺ©ν•˜μž. staticλ©€λ²„μ—λŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•  μˆ˜ μ—†μ§€λ§Œ, μ΄μ²˜λŸΌ μ œλ„€λ¦­ λ©”μ„œλ“œμ— μ œλ„€λ¦­ νƒ€μž…을 μ„ μ–Έν•˜κ³  μ‚¬μš©ν•˜λŠ” κ²ƒμ€ κ°€λŠ₯ν•˜λ‹€.

  λ©”μ„œλ“œμ— μ„ μ–Έλœ μ œλ„€λ¦­ νƒ€μž…μ€ μ§€μ—­ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 것과 κ°™λ‹€κ³  μƒκ°ν•˜λ©΄ μ΄ν•΄ν•˜κΈ° μ‰¬μšΈ 것이닀. 이 νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” λ©”μ„œλ“œ λ‚΄μ—μ„œλ§Œ μ§€μ—­μ μœΌλ‘œ μ‚¬μš©λ  κ²ƒμ΄λ―€λ‘œ λ©”μ„œλ“œμ— static을 λΆ™μΌ μˆ˜ μžˆλ‹€.

 

  μ•žμ„œ μ‚΄νŽ΄λ³΄μ•˜λ˜ makeJuice()λ₯Ό μ œλ„€λ¦­ λ©”μ„œλ“œλ‘œ λ°”κΎΈλ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

public class Juicer {
    // κΈ°μ‘΄
    static Juice makeJuice(FruitBox<? extends Fruit> box) {
        String tmp = "";
        for(Fruit f : box.getList())
            tmp += f + " ";
        return new Juice(tmp);
    }

    // μ œλ„€λ¦­ λ©”μ„œλ“œ 적용
    static <T extends Fruit> Juice makeJuice(FruitBox<T> box) {
        String tmp = "";
        for(Fruit f : box.getList())
            tmp += f + " ";
        return new Juice(tmp);
    }
}

  λ©”μ„œλ“œ ν˜ΈμΆœμ€ νƒ€μž… λ³€μˆ˜μ— νƒ€μž…μ„ λŒ€μž…ν•¨μœΌλ‘œμ¨ ν˜ΈμΆœν•  수 μžˆλ‹€.

public static void main(String[] args) {
    FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();
    FruitBox<Apple> appleBox = new FruitBox<Apple>();

    System.out.println(Juicer.<Fruit>makeJuice(fruitBox));
    System.out.println(Juicer.<Apple>makeJuice(appleBox));
}

  fruitBoxλ‚˜ appleBox의 μ„ μ–ΈλΆ€λ₯Ό ν†΅ν•΄μ„œ λŒ€μž…λœ νƒ€μž…μ„ μ»΄νŒŒμΌλŸ¬κ°€ μΆ”μ •ν•  수 μžˆλ‹€. κ·Έλž˜μ„œ μ•„λž˜μ™€ 같이 νƒ€μž…μ„ μƒλž΅ν•΄μ„œ ν‘œν˜„ν•  μˆ˜λ„ μžˆλ‹€.

public static void main(String[] args) {
    FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();
    FruitBox<Apple> appleBox = new FruitBox<Apple>();

    System.out.println(Juicer.makeJuice(fruitBox));
    System.out.println(Juicer.makeJuice(appleBox));
}

  μ§€κΈˆκΉŒμ§€ μ œλ„€λ¦­μ˜ κΈ°λ³Έ κ°œλ…λ“€μ„ μ‚΄νŽ΄λ³΄μ•˜λ‹€. κΈ€μ˜ μ„œλ‘μ—μ„œλ„ λ§ν–ˆλ“―μ΄ μ œλ„€λ¦­μ˜ λ‚΄μš©μ΄ 생각보닀 λ°©λŒ€ν•˜λ‹€. 이번 글을 톡해 κΈ°λ³Έ κ°œλ…μ„ 잘 읡히고 κ³„μ†ν•΄μ„œ μ œλ„€λ¦­μ˜ λ‹€λ₯Έ λ‚΄μš©λ“€λ„ μ‚΄νŽ΄λ³Ό 수 μžˆλ„λ‘ ν•˜μž.

 

ν•΄λ‹Ή 글은
남ꢁ성 λ‹˜μ˜ 'μžλ°”μ˜ 정석',
Inpa λ‹˜μ˜ 'μžλ°” μ œλ„€λ¦­(Generics) κ°œλ… & 문법 μ •λ³΅ν•˜κΈ°'
λ₯Ό μ°Έκ³ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

'πŸ“‚ JAVA > μ£Όμš” κ°œλ…' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

μ œλ„€λ¦­(Generics) - 곡변(Covariant), λΆˆκ³΅λ³€(Invariant), λ°˜κ³΅λ³€(Contravariant)  (0) 2023.05.29
ν˜•λ³€ν™˜(μΊμŠ€νŒ…, Casting) - μ—…μΊμŠ€νŒ…(Up-Casting), λ‹€μš΄μΊμŠ€νŒ…(Down-Casting)  (0) 2023.05.24
래퍼 클래슀 (Wrapper Class)  (0) 2023.05.09
clone()  (0) 2023.04.07
얕은 볡사(Shallow Copy) vs κΉŠμ€ 볡사(Deep Copy)  (0) 2023.04.07
  • 1. μ œλ„€λ¦­(Generic) κ°œλ… 🧱
  • 2. μ œλ„€λ¦­ 클래슀 πŸ”¨
  • πŸ“™ 1. μ œλ„€λ¦­ 클래슀 μ„ μ–Έ
  • πŸ“™ 2. μ œλ„€λ¦­ μš©μ–΄
  • πŸ“™ 3. μ œλ„€λ¦­ μ œν•œ
  • πŸ“™ 4. μ œλ„€λ¦­ 클래슀의 객체 생성과 μ‚¬μš©
  • πŸ“™ 5. μ œν•œλœ μ œλ„€λ¦­ 클래슀
  • 3. μ™€μΌλ“œμΉ΄λ“œ πŸ”§
  • πŸ“™ 1. <? extends T>
  • πŸ“™ 2. <? super T>
  • 4. μ œλ„€λ¦­ λ©”μ„œλ“œ πŸ”©
'πŸ“‚ JAVA/μ£Όμš” κ°œλ…' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
  • μ œλ„€λ¦­(Generics) - 곡변(Covariant), λΆˆκ³΅λ³€(Invariant), λ°˜κ³΅λ³€(Contravariant)
  • ν˜•λ³€ν™˜(μΊμŠ€νŒ…, Casting) - μ—…μΊμŠ€νŒ…(Up-Casting), λ‹€μš΄μΊμŠ€νŒ…(Down-Casting)
  • 래퍼 클래슀 (Wrapper Class)
  • clone()
Amenable
Amenable
CS, μžλ°”, 자료ꡬ쑰, μ•Œκ³ λ¦¬μ¦˜, μŠ€ν”„λ§, μŠ€ν”„λ§ λΆ€νŠΈμ— ν•΄λ‹Ήν•˜λŠ” κ°œλ°œμ— κ΄€ν•œ λ‚΄μš©μ„ κ³΅μœ ν•©λ‹ˆλ‹€.

ν‹°μŠ€ν† λ¦¬νˆ΄λ°”

단좕킀

λ‚΄ λΈ”λ‘œκ·Έ

λ‚΄ λΈ”λ‘œκ·Έ - κ΄€λ¦¬μž ν™ˆ μ „ν™˜
Q
Q
μƒˆ κΈ€ μ“°κΈ°
W
W

λΈ”λ‘œκ·Έ κ²Œμ‹œκΈ€

κΈ€ μˆ˜μ • (κΆŒν•œ μžˆλŠ” 경우)
E
E
λŒ“κΈ€ μ˜μ—­μœΌλ‘œ 이동
C
C

λͺ¨λ“  μ˜μ—­

이 νŽ˜μ΄μ§€μ˜ URL 볡사
S
S
맨 μœ„λ‘œ 이동
T
T
ν‹°μŠ€ν† λ¦¬ ν™ˆ 이동
H
H
단좕킀 μ•ˆλ‚΄
Shift + /
⇧ + /

* λ‹¨μΆ•ν‚€λŠ” ν•œκΈ€/영문 λŒ€μ†Œλ¬Έμžλ‘œ 이용 κ°€λŠ₯ν•˜λ©°, ν‹°μŠ€ν† λ¦¬ κΈ°λ³Έ λ„λ©”μΈμ—μ„œλ§Œ λ™μž‘ν•©λ‹ˆλ‹€.