본문 바로가기

IT/자바 Java

[Java 기초] #8. 패키지와 인터페이스

반응형

Packages 패키지


서로 관련된 클래스들은 자바의 패키지 기능을 통해 관리 할 수 있습니다. 패키지로 묶인 클래스는 패키지 이름을 통해 억세스 하게 되며, 이전 포스팅에서 설명했던 자바의 억세스 컨트롤과도 관련이 있습니다.

패키지 내의 클래스들은 다른 패키지의 클래스들과 별도의 네임스페이스 (declarative region)를 가지게 됩니다. 따라서 서로 다른 패키지 내의 클래스는 같은 이름을 가질 수 있습니다.


패키지는 코드 상단의 package 선언문을 이용해서 정의합니다. 하나의 패키지는 하나의 디렉토리를 가지며 반드시 패키지와 같은 이름을 가진 디렉토리 내에 해당 패키지의 클래스 파일들이 저장되어야 합니다.

패키지도 hierarchy를 가질 수 있습니다. 즉 상위 패키지에 속하는 여러 개의 하위 패키지를 생성할 수 있으며 하위 패키지는 상위 패키지 내의 서브디렉토리에 해당합니다.


자바의 패키지는 앞에서 설명했던 억세스 컨트롤과 밀접하게 연관됩니다.


 

 private

 default (선언문x)

protected

 public

 같은 클래스

 O

O

O

O

 같은 패키지, 서브클래스 O

 X

O

O

O

 같은 패키지, 서브클래스 X

 X

O

O

O

 다른 패키지, 서브클래스 O

 X

X

O

O

 다른 패키지, 서브클래스 X

 X

X

X

O


다른 패키지에서 정의된 클래스 멤버를 호출할때는 import 를 사용하거나 혹은 fully quialified name (패키지이름.멤버이름) 을 사용합니다.


protected members

위 표에서 설명한 것과 같이 "protected"로 선언된 멤버들은 같은 패키지에 속하거나, 해당 클래스의 서브클래스인 경우 억세스 할 수 있습니다.

즉, 슈퍼클래스와 서브클래스가 서로 다른 패키지에 속하는 경우에도 서브클래스는 슈퍼클래스에서 protected로 선언된 멤버의 억세스가 가능합니다.


import packages

다른 패키지의 클래스를 사용할 때는 위에서 언급한 대로 두 가지 방법이 있습니다. 한두번만 사용한다면 fully qualified name을 써도 되겠지만, 계속해서 쓰기가 불편하므로 보통 아래와 같이 import 를 하게 됩니다.


 import 패키지이름.클래스이름


해당 패키지의 모든 클래스를 import 하고 싶으면 단순히 * 을 사용합니다.

자바에서 기본으로 제공하는 클래스 라이브러리들도 모두 패키지에 담겨 있습니다. 자바에서는 java.lang 을 기본으로 import 합니다.


Interface 인터페이스

이전 글에서 소개했던 추상 클래스 (abstract class)는 추상 메서드 (abstract method)를 통해서 실제 구현은 서브클래스에 위임하는 대신 서브클래스가 반드시 해당 메서드를 구현하도록 강제하는 역할을 했습니다.

인터페이스는 추상 메서드와 비슷한 역할을 합니다. 인터페이스에서 정의된 메서드들은 해당 인터페이스를 사용하는 클래스에서 실제로 구현하는 코드를 정의해야 합니다. (즉 추상 인터페이스와 같습니다)

인터페이스에는 변수들도 선언될 수 있는데, 인터페이스의 변수들은 인스턴스의 변수가 아니고 상수입니다. (public, static, final)

인터페이스는 아래처럼 사용합니다.


class classname extends superclass implements interface {
// class-body
}


인터페이스를 구현하는 메서드는 반드시 public이어야 하며, type signature (이름과 파라메터 타입/수)는 인터페이스에서 정의된 것과 동일해야 합니다.

어떤 클래스가 인터페이스를 구현하는 경우 해당 인터페이스에서 정의된 메서드는 반드시 구현해야 하지만, 추상 클래스로 정의된 경우는 그렇지 않습니다. (이러한 제한은 추상 메서드와 동일합니다.)


정의된 인터페이스 타입으로 변수를 선언하는 것도 가능합니다. (interface reference variable) 그렇게 정의된 변수는 해당 인터페이스를 구현한 어떤 오브젝트도 가리킬 수 있습니다. 물론 그러한 경우 해당 변수는 인터페이스에서 정의된 멤버에 대해서만 억세스할 수 있으며 인터페이스와 관계없이 생성된 멤버는 억세스할 수 없습니다. (슈퍼클래스 타입으로 정의되어 서브클래스를 가리키는 변수의 경우와 동일합니다)


특정한 세트의 상수를 정의하고 이를 필요한 클래스에서만 사용하고자 할 때도 인터페이스를 사용합니다.

인터페이스에서 정의된 변수는 모두 상수이기 때문에, 인터페이스를 정의하고 메서드 없이 변수만 정의하고, 필요한 클래스에서 implement 하면 됩니다.


그리고, 인터페이스도 클래스처럼 다른 인터페이스를 상속할 수 있습니다. (extends 키워드 사용)


Default interface methods

자바 버전8부터는 인터페이스에서 정의하는 메서드에 실제 코드를 삽입할 수 있게 되었습니다. 그런 경우를 default method라고 부르는데, 해당 인터페이스를 구현하는 클래스에서 직접 메서드 코드를 구성하지 않고 디폴트 메서드를 사용할 수 있습니다.

디폴트 메서드는 이미 다른 많은 클래스에서 구현되고 있는 인터페이스에 메서드를 추가하는 경우 유용합니다. 인터페이스를 구현하는 모든 클래스는 추상 클래스가 아닌 경우에 무조건 인터페이스내의 모든 메서드를 구현해야 하기 때문에, 인터페이스 내의 메서드 추가는 그 인터페이스를 구현하는 모든 클래스의 코드 수정을 요구합니다. 그런 경우 새로 추가된 메서드를 디폴트 메서드 형식으로 추가한다면 기존의 클래스 코드들은 변경할 필요가 없는 거죠.

또, 인터페이스를 설계할 때 해당 인터페이스를 구현하는 클래스들이 반드시 구현해야 하는 메서드와 그렇지 않은 (즉 optional한) 메서드를 모두 포함하게 하고 싶은 경우, 후자의 경우 디폴트 메서드로 구현하면 클래스에 따라서 선택할 수 있게 됩니다.



인터페이스 내의 static 메서드

클래스 내의 static 메서드처럼, 인터페이스를 정의할 때도 static method를 선언할 수 있습니다.

인터페이스의 static 메서드도 구현체 없이 바로 사용할 수 있으며 인터페이스 이름.메서드 이름으로 호출합니다. 그리고 스태틱 메서드의 특징 상, 해당 인터페이스를 구현하는 클래스나 서브인터페이스에 상속되지 않습니다.



반응형