2016년 7월 21일 목요일

Java Programming [37강] 컬렉션

오늘은 저번에 말로만 설명했던 프레임워크의 서열(?)에 대해 설명드리겠습니다. 그리고 그를 바탕으로 가능한 다형적 대입이 활용되는 상황을 소개하겠습니다.
그림에서 보시다시피 Collection, List, Set, Map의 색깔과
Vector, Stack, ArrayList, HashSet, HashMap의 색깔이 다릅니다.
Collection무리는 모두 인터페이스입니다.
반면에 Vector~무리들은 클래스입니다.
List계열의 클래스들은 List인터페이스의 지원을 받고,
Set계열의 클래스, HashSet은 Set인터페이스의 지원을 받습니다.
마찬가지로, Map계열의 클래스, HashMap는 Map의 지원을 받습니다.

또 한가지 중요한 점은, List와 Set 인터페이스는 Collection 인터페이스로부터
각각 *상속을 받은 인터페이스입니다.
그러나 Map은 어떤 인터페이스로부터도 상속 받지 않습니다.
그리고 마지막으로 한가지 짚고 넘어가야 할 것은
Collection은 인터페이스 계의 Object와 같은 존재라는 점입니다.
Object는 클래스 세계(?)에서 모든 클래스들의 조상 클래스 였습니다.
Collection도 인터페이스 세계..에서 모든 인터페이스의 조상 인터페이스입니다.
Object의 특징에서 유추해보면.. 어떤 메소드의 매개변수가 Object 형인 경우,
그 자리에는 어떠한 클래스의 객체도 올 수 있었습니다.
Collection도 마찬가지로 어떤 메소드의 매개변수가 Collection형인 경우에는,
그 자리에는 Collection 인터페이스를 상속받은 어떠한 인터페이스도(레퍼런스타입), 그 인터페이스의 지원을 받는 어떠한 클래스의 객체 인스턴스도 올 수 있습니다. (Map인터페이스와 Map인터페이스의 지원을 받는 HashMap 제외)
Collection의 다형적 대입 특성 덕분에♥,
List계열끼리의 다형적 대입이 가능해지고,
List계열 클래스가 Set계열 쪽의 메서드를 사용하는 것이 가능(그 반대도 가능)합니다.
--------------------------------------------------------------------------------------------------
상속(extends)과 지원(implements)
클래스-클래스
클래스끼리는 "상속", 중복 상속 불가, 키워드는 extends
인터페이스-클래스
인터페이스는 클래스를 "지원"만 가능, 중복 지원 가능, 키워드는 implements
인터페이스-인터페이스
인터페이스끼리는 "상속", 키워드는 extends
--------------------------------------------------------------------------------------------------

다음의 두 가지 예를 통해 보여드리겠습니다.

1> List계열끼리의 다형적 대입



39행에서 blist에 ArrayList클래스를 객체 인스턴스화 해줄 때,
매개변수로 templist를 전달하며 생성시킵니다.
이는 다음 그림에서 보시다시피,


ArrayList<>();생성자(메서드)의 매개변수 타입이 Collection이기 때문에 가능합니다.

현재 사용하고있는 subList()메서드는 ctrl을 누른 상태에서 커서를 메서드 명에 갖다대면
이 메서드가 속한 클래스(여기서는 ArrayList)를 기준으로 재정의, 인터페이스(List) 지원, 조상 인터페이스(Collection) 지원, 반환형(List<>()) 등에 관한 정보를 볼 수 있는데요. 

이를 통해 유추해볼 수 있는 것은 subList()메서드는 ArrayList 클래스를 지원하는 인터페이스인 List나 Collection 적어도 둘 중 하나에는 존재하다가 ArrayList 클래스가 alist라는 이름으로 객체화 될 때 강제재정의 되었다는 것입니다.
이 메서드의 반환형은 List<>() 타입인데, List는 인터페이스이므로 객체 인스턴스화 될 수 없으므로 소스사진의 37행에서처럼 레퍼런스 변수에 담았습니다.
  이 레퍼런스 변수는 List 형 이므로 
ArrayList<>();생성자의 매개변수 타입인 Object보다
"작아서" 다형성에 의해 대입이 가능합니다.

그런데 templist를 사용한 것은 blist를 객체 인스턴스화 해주는 과정에서 Arraylist<>()생성자 메서드에 매개변수를 전달해주기 위한 목적이므로 차라리 다음과 같이 한줄로 코딩이 가능합니다.
Arraylist<Integer>() blist = new Arraylist<Integer>(alist.subList(1,4)); 

뒤에서 HashSet클래스(Set의 지원을 받는 클래스)에 대해 자세히 설명하겠지만 다음의 소스도 Collection의 다형성 대입으로 가능한 경우입니다.


2>List계열 클래스가 Set계열 쪽의 메서드를 사용하는 것이 가능(그 반대도 가능)


68행은 Collections클래스의 메서드 sort()함수를 호출할 때 매개변수로 set을 바로 넘기면 에러가 발생한다는 것을 말하고 싶었습니다.


sort()메서드의 매개변수 타입은 List<> 입니다.
set은 HashSet 클래스(HashSet은 Set인터페이스 만의 지원을 받지, List 인터페이스의 지원은 받지 않는다.) 이므로 다형적 대입이 불가한 관계입니다.
ArrayList<>();생성자의 매개변수 타입은 Collection이고 다행히 HashSet도 Collection 인터페이스의 지원은 받으므로(Collection이 Set에 상속되고, Set은 HashSet을 지원) 다음과 같이 ArrayList<>();생성자의 매개변수로 set을 넘기고 객체 인스턴스화 하여 ArrayList형 객체 인스턴스를 sort()의 매개변수로 넘깁니다. (69~71행)
아니면 간단히 다음 한 줄로도 코딩이 가능합니다.




다음시간에는 컬렉션의 요소를 빠르게 꺼내오는 키워드, Enumeration과 Iterator에 대해서 공부해보겠습니다.

댓글 없음:

댓글 쓰기