2009-09-27 3 views
17

이것은 실제 초보자 용 질문입니다 (아직 Java 기초를 배우고 있습니다). 방법은 목록 < 문자열 >보다는 ArrayList를 < 문자열 >, 또는 왜 그들이 목록 매개 변수보다는 ArrayList의를 받아들이을 반환하는 이유변수가 Java에서 인터페이스 이름으로 선언되는 이유는 무엇입니까?

나는 (일종의)을 이해할 수있다. 메소드에 아무런 차이가없는 경우 (즉, ArrayList의 특별한 메소드가 필요하지 않은 경우), 메소드를보다 융통성 있고 호출자에게 사용하기가 더 쉬워집니다. Set 또는 Map과 같은 다른 콜렉션 유형도 마찬가지입니다.

는 이해가 안 무엇 :이 양식은 덜 자주하지만

List<String> list = new ArrayList<String>(); 

:

ArrayList<String> list = new ArrayList<String>(); 

장점이 여기에 무엇인가가 일반적인 같은 지역 변수를 만드는 연습 것으로 보인다?

필자가 볼 수 있듯이 사소한 단점이 있습니다. java.util.List에 대한 별도의 "가져 오기"행을 추가해야합니다. 기술적으로 "import java.util. *"을 사용할 수는 있지만 그 중 일부는 표시되지 않습니다. 이는 "가져 오기"행이 일부 IDE에서 자동으로 추가 되었기 때문일 수 있습니다.

답변

20

당신은 모든 당신이 List<String>을되고있는 신경 있다는 생각을하면 실제 구현에 덜 중점을두고. 또한 특정 구현이 아닌 List<String>으로 선언 된 회원으로 자신을 제한 할 수 있습니다. List<String>처럼 보이는 경우 데이터가 선형 배열 또는 멋진 데이터 구조에 저장되어 있는지 신경 쓰지 않아도됩니다.

반면에 두 번째 줄을 읽으면 코드 ArrayList<String> 인 것을 염려합니다. 이것을 쓰면 코드의 나머지 부분이 인데 실제로는 ArrayList<String>이라는 사실에 따라에 의존하기 때문에 실제 개체 유형을 맹목적으로 변경해서는 안된다는 것을 암시 적으로 (향후 독자들에게) 말합니다.

+5

이것은 초록 필리아입니다. 한 구현의 효율성과 다른 구현의 효율성은 변수를 사용하는 코드에 따라 달라집니다. 두 코드 간의 긴밀한 결합을 원할 수는 없습니다. –

+0

"나는 둘 사이에 단단한 커플 링을 원한다는 것을 알지 못합니다."사실 인터페이스에 대한 전체 개념이 실제로 느슨한 커플 링을 원한다는 사실에 근거하지 않습니까? –

+1

물론.그러나 함수의 작업과 지역 변수 간의 결합이 느슨 할 때를 원하십니까? 특히 콜렉션 구현을 선택할 때, 콜렉션은 특정 상황에 맞게 종종 최적화되기 때문에. –

1

나중에 목록의 구현을 변경하고 예를 들어 LinkedList (성능 향상을 위해)를 사용하려는 경우 전체 코드 (및 해당 라이브러리 인 경우 API)를 변경하지 않아도됩니다. 주문이 중요하지 않은 경우 나중에 컬렉션을 반환해야합니다. 그러면 항목을 정렬해야하는 경우 Set으로 쉽게 변경할 수 있습니다.

+0

"왜 메소드는 ArrayList "<- so API;)가 아닌 List 을 반환합니다. – IAdapter

1

가장 좋은 설명은 (내가 다른 언어에서와 같이 자주 자바로 프로그래밍하지 않기 때문에) 동일한 코드/코드를 유지하면서 "백엔드"목록 유형을 변경하는 것이 더 쉽다는 것입니다. 인터페이스는 다른 모든 것에 의존합니다. 더 구체적인 유형으로 선언 한 다음 나중에 다른 종류를 원한다고 결정하면 ... ArrayList 특정 메서드를 사용하면 뭔가가 추가 작업이됩니다.

실제로 ArrayList 관련 동작이 필요한 경우에는 특정 변수 유형을 사용하는 것이 좋습니다. 당신이

List<String> list = new ArrayList<String>(); 

을 읽을 때

7

인터페이스를 사용하면 List/Map/Set/등의 기본 구현을 빠르게 변경할 수 있습니다.

키 입력을 저장하는 것이 아니라 구현을 빠르게 변경하는 것입니다.원칙적으로 구현의 기본 메서드를 노출하지 않고 필요한 인터페이스 만 사용해야합니다.

2

나는 다른 끝에서 이것을 생각할 것을 제안합니다. 일반적으로 List 또는 Set 또는 다른 Collection 유형이 필요합니다. 코드가 실제로 구현되는 방법을 신경 쓰지 않아도됩니다. 따라서 귀하의 코드는 List와 함께 작동하며 필요한 모든 작업을 수행합니다 ("항상 인터페이스에 코드"라고도 함).

목록을 만들 때 원하는 실제 구현을 결정해야합니다. 대부분의 경우 ArrayList는 "충분 함"이지만 코드는 실제로 신경 쓰지 않습니다. 인터페이스를 계속 사용함으로써 미래의 독자에게 전달할 수 있습니다.

예를 들어 시스템 속성을 System.out에 덤프하는 내 기본 메서드에서 디버그 코드를 사용하는 습관이 있습니다. 일반적으로 정렬하는 것이 훨씬 더 좋습니다. 가장 쉬운 방법은 단순히 "Map map = new TreeMap (properties);" TreeMap가 정렬 된 키를 반환하므로 THEN이이를 반복합니다.

Java에 대해 더 많이 배우면 인터페이스가 테스트 및 조롱에 매우 유용하다는 것을 알 수 있습니다. 특정 인터페이스에 따라 런타임에 지정된 동작을 사용하여 객체를 만들 수 있기 때문입니다. 고급 (그러나 간단한) 예가 다음에서 볼 수 있습니다. http://www.exampledepot.com/egs/java.lang.reflect/ProxyClass.html

-2

기본적으로 이것은 큰 프로젝트를 실행해야하는 사람들로부터 온 것입니다. 왜, 나는 실제로 모른다. 배열 목록이나 해시 맵 또는 해시 세트가 필요하거나 인터페이스에 캐스팅하여 메서드를 제거하는 데 아무런 의미가없는 경우는 무엇이든 참조하십시오.

예를 들어, 최근에 나는 HashSet을 기본 데이터 구조로 사용하고 구현하는 방법을 배웠습니다. 어떤 이유에서 건 팀에 취업했다고 가정 해 봅시다. 그 사람은 데이터가 어떤 근거에 의해 명령을받는 것이 아니라 해싱 접근법에 맞추어 졌다는 것을 알아야 할 필요가 없을까요? Twisol이 지적한 백 엔드 접근법은 헤더를 노출하고 라이브러리를 판매 할 수있는 C/C++에서 작동합니다. Java에서이를 수행하는 방법을 알고 있다면 JNI를 사용할 것이라고 생각합니다. 어느 시점에서 나에게 더 간단한 것처럼 보입니다. C/C++을 사용하여 헤더를 노출하고 그 목적을 위해 기존 도구를 사용하여 라이브러리를 빌드 할 수 있습니다.

확장 프로그램 디렉토리에 jar 파일을 설치할 수있는 사람이 생길 무렵 엔 엔티티가 짧은 단계 만 남았을 것 같습니다. 확장 디렉토리에 몇 개의 암호화 라이브러리를 떨어 뜨 렸지만 편리했습니다. 분명히 명확하고 간결한 토대가 밝혀 지길 바랍니다. 나는 그들이 항상 그렇게한다고 상상한다.

이 시점에서 나는 고전적인 난독 화처럼 들리지만 다음과 같은주의를 기울여야합니다. 문제가 발생하기 전에 코딩을해야합니다.

+0

끝까지 나를 완전히 잃어 버렸습니다. – user183037

+2

그리고 나. 당신은 인터페이스의 요점을 놓친 것 같습니다. 또한 여기에 캐스팅이 없습니다. – DNA

0

요점은 원하는/원하는 동작을 식별 한 다음 해당 동작을 제공하는 인터페이스를 사용하는 것입니다. 변수의 유형입니다. 그런 다음 다른 요구 사항 (효율성 등)을 충족시키는 구현을 사용하십시오. 이것은 "새"로 작성하는 것입니다. 이 이중성은 OOD의 주요 아이디어 중 하나입니다. 이 문제는 지역 변수를 다룰 때 특히 중요하지는 않지만 항상 좋은 코딩 방법을 따르는 일은 거의 없습니다.

관련 문제