알고리즘 문제 풀기 6일차
1. Generics
- 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시 타입 체크를 해주는 기능
- 객체 타입을 컴파일 시에 체크하기 때문에 타입 안정성을 높이고 형변환의 번거로움이 줄어듦
- 저장된 객체를 꺼낼 때 형변환이 필요 없어서 편하다. > 코드가 간결해 진다
1)타입 변수
- 클래스 이름 옆의 < > 안에 작성, 반드시 작성할 필요는 없다.
- 아래와 같이 타입 변수를 대입한 경우 형 변환이 불필요 하다.
ArrayList tvlist = new ArrayList();
tvlist.add(new Tv());
Tv t = (TV)tvlist.get(0);
ArrayList<Tv> tvlist = new ArrayList<Tv>();
tvlist.add(new Tv());
Tv t = tvlist.get(0);
2)Generics 클래스와 다양성
ㄱ. 아래와 같이 제너릭스 클래스를 작성할 수있다.
- Box<T> : 지네릭 클래스.
- T : 타입 변수 또는 타입 매개변수
- Box : 원시 타입(raw type)
class Box<T> {}
- Box<String> , Box<Integer> 와 같이 사용가능하며, 서로 다른 타입을 대입하여 호출했지만 별개의 클래스는 아니다.
ㄴ. 지네릭 타입과 다형성
- 상속 관계가 있는 클래스라 하더라도 타입은 일치되어야 한다.
- 와일드 카드(?) 를 이용하면 자손 클래스도 가능하다
- <? extends T>상한제한으로 T와 자손만 가능, <? super T>하한제한으로 T와 조상만 가능, <?> 제한 없음
ArrayList<tv> list = new ArrayList<Tv>();
ArrayList<Product> list = new ArrayList<Tv>(); // 에러, 불일치
List<? extends Product> list = new ArrayList<Tv>();
List<? extends Product> list = new ArrayList<Audio>();
- 지네릭 타입이 아닌 클래스의 타입간에 다형성을 적용하는 것이 가능하며, 이때 지네릭 타입도 일치해야한다.
List<tv> list = new ArrayList<Tv>();
List<Tv> list = new LinkedList<Tv>();
- 자손의 객체를 저장하는 것은 가능하다. 다만 꺼내올 때는 형변환이 필요하다.
- 다른 클래스도 추가가 가능하다, 경우에 따라 자손 타입으로만 제한 할 수 있다.
ArrayList<Product> list = new ArrayList<Product>();
list.add(new Product());
list.add(new Tv());
list.add(new Audio());
Product p - list.get(0);
Tv t = (Tv)list.get(1);
//제한하지 않았을 때, 과일상자에 장난감도 담을 수 있다.
FruitBox<Toy> fruitBox = new FruitBox<Toy>();
fruitBox.add(new Toy());
//제한하고 선언한 경우
class FruitBox<T extends Fruit>{
ArrayList<T> list = new ArrayList<T>();
}
FruitBox<Apple> appleBox = new FruitBox<apple>();
FruitBox<toy> appleBox = new FruitBox<Toy>(); // 에러가 발생
ㄷ. Iterator<E>
- 앞서 언급한 편의성과 이어진다.
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("홍길동",1,1));
list.add(new Student("장동건",1,2));
list.add(new Student("김남길",2,1));
Iterator<Student> it = list.iterator();
while (it.hasNext()){
//Student s = (Student)it.next();// 지네릭스를 하용하지 않을때 형변환 필요
Student s = it.next();
}