ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 18일차 - 제네릭, 와일드카드, 컬렉션 프레임 워크
    AI 솔루션 개발자과정(Java, Python) 2022. 11. 2. 17:12

    제네릭

    제네릭 기반의 클래스는 자료형의 타입을 나중에 정한다.

    클래스 내부에서 사용할 데이터의 타입을 외부에서 정할 수 있다.

    타입 매개변수로는 어떠한 문자도 사용할 수 있지만, 대문자 하나로 쓰는것이 묵시적인 약속이다.

     

    코드를 작성하다 보면, 컴파일 에러가 나지 않았지만 실행했을때 예외가 발생하는 경우가 있다.

    실행과정에서 조차 에러가 발견이 안되는 경우도 있다.

    제네릭을 사용하면 컴파일 단계에서 에러가 난다.

    또한 오브젝트 타입을 기반으로 하기 때문에 명시적 형 변환이 되어 별도의 형 변환작업이 필요없다.

     

    제네릭의 기본 문법

    Box<Apple> aBox = new Box<Apple>();
    제네릭은 참조 변수를 선언할 때, 참조대상의 타입인자를 따로 입력해 주지 않아도, 컴파일러에 의해 참조 변수의 타입인자를 참조 대상에 와야한다고 유추하여 적용한다.
    따라서 참조 대상의 타입인자를 생략해도 된다.
    Box<Apple> aBox = new Box<>();

     

    자바 기본 자료형은 제네릭 기반 클래스에 타입 인자로 전달할 수 없다.

    이는 래퍼 클래스로 대체한다.

     

    매개변수화 타입을 타입인자로 사용할 수 있다.

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

    Box<Box<String>> wBox = new Box<>();

    Box<Box<Box<String>>> zBox = new Box<>();

    a박스를 받는 b박스가 있고, b박스를 포함하는 c박스가 있다. 이 매개변수화 타입들또한 타입인자로 받을 수 있다.

     

     

    제네릭 클래스의 타입 인자를 제한하기

    class Box<T extends Number> {...}

       → 인스턴스 생성 시 타입 인자로 Number 또는 이를 상속하는 클래스만 올 수 있음

    타입인자를 제한하지 않으면 어떤 타입인자가 올지 모르기 때문에 에러가 발생한다.

     

    제네릭 클래스의 타입 인자를 인터페이스로 제한하기

    클래스와 마찬가지로 인터페이스 또한 제한할 수 있다.

    인터페이스가 가지고 있는 메소드를 사용할 수 있고, 클래스와 인터페이스를 동시에 제한할 수도 있다.

     

    제네릭 메소드의 정의

    제네릭 메소드를 정의할 때는 리턴타입의 앞에 타입 매개변수 <T>를 붙이고, 리턴값과 메소드의 매개변수에 타입 매개변수를 넣어주어 정의한다.

     

    제네릭 메소드의 제한된 타입 매개변수 선언

    인스턴스 메소드는 인스턴스 존재 이후의 메소드이다.
    따라서 멤버 변수를 제네릭 기반으로 정하고 메소드 자체는 그냥 만들어서 쓰는 경우가 편하다.
    클래스 메소드는 독립적으로 기능을 제공할 수 있어야 하기 때문에 클래스 메소드를 제네릭 기반으로 만드는 경우가 더 많다.

     

     

    제네릭의 심화 문법

    제네릭 클래스와 상속

    제네릭 기반의 클래스를 상속하려면, 제네릭 기반의 클래스로 만들어야 한다.

    그렇지 않으면 에러가 난다.

     

     

    타입 매개변수가 같을 때만 부모 자식 간의 관계가 성립이 된다.

    자바에서는 다중상속을 지원하지 않기 때문에 타입 매개변수가 같다면 생략이 가능한 것이다.

     

    타겟 타입

    제네릭 메소드이기 때문에 makeBox()의 앞에 타입 매개변수가 와야 하지만 참조변수의 형을 기반으로 타입 매개변수가 결정되기 때문에 생략한다.

     

     

    와일드카드

    두 코드는 제네릭 메소드와 일반 메소드이다. 제네릭 메소드는 Integer나 String 을 인자로 전달받을 수 있지만, 일반 메소드는 받을 수 없다.

    그러나 와일드카드를 사용하면 일반 메소드도 이런 두 인스턴스를 인자로 받을 수 있다.

     

    와일드카드 기반의 메소드는 타입 매개변수에 ? 를 사용한다.

     

    두 메소드는 기능적으로 완전히 동일하다.

    그러나 와일드카드 기반의 메소드가 더 간결하므로 우선시 해야 한다고 권고하고 있다.

    메소드의 정의가 복잡해질수록 와일드카드 기반 메소드가 더 간결해 보인다.

     

    와일드 카드의 상한과 하한의 제한: Bounded Wildcards

    상한 제한된 와일드카드(Upper-Bounded Wildcards)
    하한 제한된 와일드카드(Lower-Bounded Wildcards)

    상한 제한된 와일드카드는 extends 키워드를 사용한다.

    하한 제한된 와일드카드는 super 키워드를 사용한다.

     

    제네릭 메소드는 상한제한만 가능하다. 와일드카드는 상한, 하한제한 모두 가능하다.

     

     

     

    와일드카드 제한의 이유

    장난감을 넣을 수 있는 상자를 만든다.

    장난감을 넣기만 하려고 만든 박스인데 장난감이 꺼내진다.

    반대로 꺼내려고 만든 박스인데 장난감이 넣어진다. 

    의도와는 다른 결과가 만들어지고, 컴파일 오류가 발생하지 않는다. 

    이를 해결하기 위해 와일드카드 제한이 있다.

     

     

    상한 제한의 목적

    Box의 타입 매개변수는 Toy 자신과 Toy를 상속하는 자식 클래스의 인스턴스들만 넣을 수 있게 된다.

     

     

     

    하한 제한의 목적

    Toy는 Plastic을 상속한다. Box는 Toy로 하한 제한을 걸었기에 상속받은 Toy 아니면 Plastic의 인스턴스만 인자로 받을 수 있다. 

    즉 부모 클래스의 인스턴스만을 사용할 수 있다.

     

     

     

    제한된 와일드카드 선언을 갖는 제네릭 메소드

    컴파일 과정에서 < . . . > 내용이 모두 지워진다. 따라서 컴파일러가 이러한 형태의 메소드 오버로딩을

    허용하지 않음.

    와일드 카드간의 오버로딩은 불가능하다.

     

    그래서 와일드카드 선언을 갖는 제네릭 메소드로 작성한다.

     

     

    제네릭 인터페이스의 정의와 구현

     

    인터페이스 역시 클래스와 마찬가지로 제네릭으로 정의할 수 있다.

     

     

     

     

     

    컬렉션 프레임 워크

    자료구조 : IT 학문 분야 중 하나

     - 어떻게 하면 효율적으로 자료를 관리할까?

     - 그 질문에 대한 대답 몇 가지들

     

    컬렉션 프레임 워크는 자바에서 자료 구조를 정의해 제공하는 표준 인터페이스 형태로 제공하는 것이다.

    컬렉션 프레임 워크는 자료 구조 및 알고리즘을 구현해 놓은 일종의 라이브러리이다.컬렉션 프레임 워크는 제네릭 기반으로 만들어 졌다.

     

     

     

    List<E> 인터페이스

    인터페이스는 인스턴스를 생성할 수 없기 때문에 자바는 인터페이스를 구현하는 컬렉션 클래스를 제공한다.

     

     

     

    ArrayList<E> 클래스

    배열 기반의 자료 구조이지만 공간의 확보 및 확장은 ArrayList 인스턴스가 스스로 처리한다.

    add 는 자료를 추가한다
    size 는 length의 역할을 한다.

    get 은 자료를 내보낸다

     

     

    LinkedList<E>

    ArrayList가 LinkedList로 바뀐 것이 유일한 변화이다.

     

     

     

    ArrayList<E> 와 LinkedList<E> 의 장.단점

    ArrayList<E>의 단점

     - 저장 공간을 늘리는 과정에서 시간이 비교적 많이 소요된다.
           ArrayList는 배열 기반이기 때문에 자료를 추가하려면 단순히 추가하는 것이 아닌 배열을 다시 만들고,  복사           하는 작업을 해야한다.
     - 인스턴스의 삭제 과정에서 많은 연산이 필요할 수 있다. 따라서 느릴 수 있다.

    ArrayList<E>의 장점

     - 저장된 인스턴스의 참조가 빠르다.

    LinkedList<E>의 단점

    - 저장된 인스턴스의 참조 과정이 배열에 비해 복잡하다. 따라서 느릴 수 있다.
          배열과 달리 인덱스가 없기 때문에 참조 값을 데이터에 만들어야한다.

    LinkedList<E>의 장점

     - 저장 공간을 늘리는 과정이 간단하다.
     - 저장된 인스턴스의 삭제 과정이 단순하다.

     

     

     

    배열보다 컬렉션 인스턴스가 좋은 이유

    인스턴스의 저장과 삭제가 편하다.반복자를 쓸 수 있다.

     

    단, 배열처럼 선언과 초기화를 동시에 할 수가 없다. 그러나 다음 방법으로 비슷한 기능을 할 수 있다.

     

    리스트만 갖는 양방향 반복자

     

     

    Set<E> 인터페이스를 구현하는 컬렉션 클래스들

     

    동일 인스턴스에 대한 기준은?

     

    해쉬 알고리즘

     

     

     

     

Designed by Tistory.