[스터디-자바] 지네릭스 개념과 예제 풀이

jh5959·2025년 5월 1일
0

스터디를 합시다

목록 보기
5/5

마지막 발표

강의 날짜:4/30(수)

드디어 마지막이다 마지막인만큼 내가 이해하지 못했던 개념에 대해서 설명하려고 지네릭스를 주제로 선정했다
이해가 안돼서 공부를 미뤘는데 발표를 핑계로 공부했다
처음에는 이해가 안됐는데 계속 보다보니까 알 것 같기도 하다

이번에도 개념 설명은 다른 분이 하고 나는 그거에 맞춰서 코드 설명을 했다

벌써 네번이나 해서 그런지 처음했을 때보다 긴장도가 덜 해진거 같다 확실히 도움이 많이 된듯하다... 이제는 개념공부와 더불어서 실습을 더 많이 하려고 한다 스터디는 이제 끗


주제: 지네릭스 개념과 예제풀이

지네릭스

: 컴파일 시 타입 체크

  • 타입 안정성 확보

  • 형변환없이 사용 가능 -> 코드 간결

  • Object 타입의 문제점
    - 모든 타입을 받을 수 있지만 꺼낼 때 형변환 필요 -> 런타임 에러 위험 있음

Box b = new Box();
b.set("Hello");
Integer i = (Integer) b.get(); // ❗ 런타임 오류!

지네릭 클래스의 객체 생성과 사용

참조변수와 생성자에 대입된 타입(매개변수화된 타입)이 일치해야 함

Box<Apple> appleBox = new Box<Apple>();

Box<Fruit> appleBox = new Box<Apple>(); //상속 관계여도 호환X, 타입이 정확히 같아야 함

Box<Apple> appleBox = new fruitBox<Apple>(); //다형성, 가능함

제한된 지네릭 클래스

지네릭 타입에 extends를 사용하면 특정타입의 자손들만 대입 할 수 있게 제한

class FruitBox<T extends Fruit> 
//Fruit와 그의 자손 가능

와일드 카드

<? extends T>
: 와일드 카드의 상한 제한, T와 그 자손들만 가능

<? super T>
: 와일드 카드의 하한 제한, T와 그 조상들만 가능

<?>
:제한 없음, 모든 타입 가능, <? extends object> 와 동일

12-3 예제 풀이

import java.util.ArrayList;  
  
class Fruit2 {public String toString(){return "Fruit";}}  
class Apple2 extends Fruit2 {public String toString(){return "Apple";}} //Fruit2클래스를 상속받음  
class Grape2 extends Fruit2 {public String toString(){return "Grape";}}//Fruit2클래스를 상속받음  
  
class Juice{//주스 문자열을 더해주는 클래스  
    String name;  
  
    Juice(String name){this.name=name+ "Juice";}//매개변수가 있는 생성자,매개변수로 받은 name에 "juice" 문자열을 더해 iv 변수 name에 저장  
    public String toString(){return name;}//toString으로 name 반환  
}  
  
class Juicer{//주스를 만드는 클래스  
    static Juice makeJuice(FruitBox1<? extends Fruit2> box){//juice객체를 반환하는 makeJuice메서드  
        //매개변수 box의 타입이 Fruit2와 그 자손들 가능  
        //FruitBox1<Fruit2> 이렇게 쓰면 Fruit2인 타입만 가능함 / 그래서 와일드카드로 자손도 가능하게 만듦  
        //static Juice makeJuice(FruitBox1<T extends Fruit2> box) ->문법오류 메서드 매개변수에는 타입 매개변수 T를 쓸 수 없음  
        String tmp="";  
  
        for(Fruit2 f : box.getList())//box안에 있는 Fruit2의 객체(Apple2,Grape2)을 하나씩 꺼냄  
            tmp+=f+" ";//tmp에 객체의 toString을 호출해서 문자열로 만듦  
        return new Juice(tmp);//juice 객체 생성과 매개변수가 있는 생성자로 초기화  
    }  
  
}  
public class Ex12_3 {  
    public static void main(String[] args) {  
        FruitBox1<Fruit2> fruitBox=new FruitBox1<Fruit2>();  
        FruitBox1<Apple2> appleBox=new FruitBox1<Apple2>();  
  
        fruitBox.add(new Apple2());  
        fruitBox.add(new Grape2());  
        appleBox.add(new Apple2());  
        appleBox.add(new Apple2());  
        //appleBox.add(new Grape2()); 에러 타입이 다름, appleBox는 타입이 Apple이라 Apple만 가능  
  
        System.out.println(Juicer.makeJuice(fruitBox));//참조변수 fruitBox를 makeJuice메서드의 매개변수로 넘겨줌  
        System.out.println(Juicer.makeJuice(appleBox));  
  
    }  
}  
  
class FruitBox1<T extends Fruit2> extends Box2<T>{}  
//FruitBox1의 클래스의 타입은 Fruit2와 그 자손들(타입제한)  
//Box2 지네릭 클래스를 상속받아 그 멤버 사용가능  
  
class Box2<T>{//제네릭 클래스임  
    ArrayList<T> list= new ArrayList<T>();//데이터 저장 arraylist가 담당  
    void add(T item){list.add(item);}  
    T get(int i){return list.get(i);}  
    ArrayList<T> getList(){return list;}//list의 값을 반환  
    int size(){return list.size();}  
    public String toString(){return list.toString();}  
}

T vs ? 차이

  • <T extends X>: 메서드 내부에서 T를 직접 쓸 때 사용
  • ? extends X: 타입을 받기만 하고 내부에서 타입 이름 쓸 필요 없을 때 사용 → 간단함

셀프 피드백

  • 코드를 진짜 많이 들여다보고 말로 설명해봐서 발표할 때 막히지는 않았다
  • 다만 질문에 답을 못했는데 그 질문에 대한 답을 아주 얕게 알고 있어서 답을 못했다
  • 분명히 나도 궁금해서 지피티한테 물어봤는데 그냥 대충 답보고 넘겨버림
  • 다음에는 그런 부분에서 더 디테일하게 알아봐야겠다는 생각이 들었다
  • 마지막인 만큼 잘했다고 칭찬해주고 싶다 중간에 그만두고 싶었지만 끝까지 발표를 마쳤다 잘했다!

0개의 댓글