제네릭스 (Generics)
제네릭스란?
제네릭스는 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능이다.
객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움이 줄어든다.
📌출처: https://history1994.tistory.com/20
ArrayList 자료구조 사용
- 배열과 달리 요소의 개수가 가변적이다.
- 인덱스를 이용해서 요소에 접근할 수 있다.
- ArrayList는 객체만 저장할 수 있다. 즉, 기본형은 저장할 수 없다.
- Object 클래스 또는 그 후손 클래스 객체만 저장 가능하다.
ArrayList list = new ArrayList();
list.add("Seoul");
list.add(new String("Tokyo"));
list.add(new Integer(3));
list.add(5); //boxing
ArrayList란?
ArrayList는 List 인터페이스를 상속받은 클래스로 크기가 가변적으로 변하는 선형리스트입니다. 일반적인 배열과 같은 순차리스트이며 인덱스로 내부의 객체를 관리한다는점등이 유사하지만 한번 생성되면 크기가 변하지 않는 배열과는 달리 ArrayList는 객체들이 추가되어 저장 용량(capacity)을 초과한다면 자동으로 부족한 크기만큼 저장 용량(capacity)이 늘어난다는 특징을 가지고 있습니다.
📌출처: https://coding-factory.tistory.com/551
기존 ArrayList의 문제점
- 어떤 종류의 객체든 저장 가능 -> 장점 겸 단점으로 너무 섞여서 구분이 불가한 경우가 생기며 사용자가 데이터 타입을 모두 숙지하여 형변환 해주어야 한다.
- 객체를 사용할 때 형변환 필요 - 다운 캐스팅
- 어디에 어떤 클래스형 자료가 있는지를 정확하게 숙지하고 있어야 함
- 대부분 단일 자료형만 저장
String s1 = list.get(0); //오류 발생
String s1 = (String) list.get(1);
String s1 = (String) list.get(2); //예외 발생
Integer i1 = (Integer) list.get(2);
int i2 = (Integer) list.get(3);
제네릭스 (Generics)
1. ArrayList에 단일 자료형을 저장할 때 효율적으로 사용하는 방법이 제네릭스를 사용하는 것이다.
-> 이때 단일 자료형이 아니라면 기존 Object와 다름이 없다.
2. 제네릭스의 사용법
■ 자료구조 <자료형>
ArrayList<String> list = new ArrayList<String>();
// ArrayList<String> list = new ArrayList<>();
list.add("Seoul");
list.add(new String("Tokyo"));
list.add(new Integer(3)); // 오류 발생
String s = list.get(0); // 형 변환 필요 없음
기존 ArrayList를 이용해서 제네릭스 ArrayList를 만들기
class MyArrayList<String> {
ArrayList list;
public MyArrayList() {
list = new ArrayList();
}
public void add(String e) {
list.add(e);
}
public String get(int i) {
return (String) list.get(i);
}
}
class MyArrayList<Integer> {
ArrayList list;
public MyArrayList() {
list = new ArrayList();
}
public void add(Integer e) {
list.add(e);
}
public Integer get(int i) {
return (Integer) list.get(i);
}
}
class MyArrayList<E> {
ArrayList list;
public MyArrayList() {
list = new ArrayList();
}
public void add(E e) {
list.add(e);
}
public E get(int i) {
return (E) list.get(i);
}
}
MyArrayList<String> l = new MyArrayList<String>();
l.add("temp");
l.add("add");
String s = l.get(0)
제네릭스(Generics) - 구현 예제
n철자 확인(spell checking)하는 기능과 다른 문서 파일 포맷으로 저장하는 기능을 갖춘 워드 프로세서 클래스 구현 후 검수하는 프로그램 작성
<WordProcessor 클래스>
import java.util.HashMap;
import java.util.Map;
public class WordProcessor {
private ISpellChecker spellChecker;
private Map<String, DocConverter> converters;
private String fileName;
public WordProcessor(String fileName) {
this.fileName = fileName;
converters = new HashMap<String, DocConverter>();
}
public void addDocConverter(DocConverter converter) {
converters.put(converter.getExtension(), converter);
}
public void convertDocTo(String ext) {
if (converters.containsKey(ext)) {
DocConverter c = converters.get(ext);
c.save(fileName);
}
}
public void setSpellChecker(ISpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void checkSpelling() {
if (spellChecker != null) {
spellChecker.check();
}
}
}
<Main class>
public class Main {
public static void main(String[] args) {
WordProcessor wp = new WordProcessor("new doc");
wp.setSpellChecker(new EngSpellChecker());
wp.addDocConverter(new DocxDocConverter());
wp.addDocConverter(new PdfDocConverter());
wp.addDocConverter(new OdtDocConverter());
wp.checkSpelling();
wp.convertDocTo("odt");
wp.convertDocTo("pdf");
wp.convertDocTo("docx");
wp.convertDocTo("wps");
}
}
<ISpellChecker interface>
public interface ISpellChecker {
void check();
}
<ISpellChecker interface를 구현한 EngSpellChecker 클래스>
public class EngSpellChecker implements ISpellChecker {
@Override
public void check() {
System.out.println("Checking English Spelling...");
}
}
<DocConverter abstract>
public abstract class DocConverter {
private String ext;
public DocConverter(String extension) {
ext = extension;
}
public String getExtension() {
return ext;
}
public abstract void save(String fileName);
}
<DocxDocConverter를 상속받아 구현한 클래스들>
public class PdfDocConverter extends DocConverter {
public PdfDocConverter() {
super("pdf");
}
@Override
public void save(String fileName) {
System.out.printf("%s.%s로 변환해서 저장합니다\n",
fileName, getExtension());
}
}
public class OdtDocConverter extends DocConverter {
public OdtDocConverter() {
super("odt");
}
@Override
public void save(String fileName) {
System.out.printf("%s.%s로 변환해서 저장합니다\n",
fileName, getExtension());
}
}
# getExtension( ) 확장자를 가져오는 함수이다.
'Java > 고급객체지향' 카테고리의 다른 글
고급객체지향 프로그래밍 - 데코레이터 패턴 (Decorator Pattern) (0) | 2021.10.19 |
---|---|
고급객체지향 프로그래밍 - 스윙 (Swing) (0) | 2021.10.18 |
고급객체지향 프로그래밍 - 옵서버 패턴 (Observer Pattern) (0) | 2021.10.18 |
고급객체지향 프로그래밍 - 전략 패턴strategy pattern) (0) | 2021.10.18 |
#1. 과제 (0) | 2021.09.17 |