공부/whiteship-java

7주차: 패키지

chulphan 2021. 1. 1. 21:13

백기선님께서 주최하시는 온라인 자바 스터디

github.com/whiteship/live-study

 

whiteship/live-study

온라인 스터디. Contribute to whiteship/live-study development by creating an account on GitHub.

github.com

어느덧 7주차가 되었다. (4주차부터 참여했지만...0_0)

 

7주차 과제는 패키지이고 아래와 같은 내용을 공부하는 과제이다

 

7주차 과제

 

▶ package 키워드

패키지 키워드란?

  • 비슷한 타입의 클래스, 인터페이스, enumerate, annotation 그리고 서브 패키지들의 그룹. 
  • 자바 클래스에 대한 namespace 를 제공한다 => 패키지 이름이 유일하다는 것을 보장한다
  • 소스코드의 상단에 위치해야한다 (어떠한 statement 보다 우선 되어야 함)
  • 패키지 이름은 level1.level2.....levelN 의 패턴을 따른다

 

JAVA 의 패키지는 두 가지 형태로 분류 된다

 

  • built-in: java.lang, awt, javax, swing 과 같이 자바에서 지정해놓은 패키지
  • user-defined: 말 그대로 프로그래머가 정의한 패키지

자바 패키지 사용에 대한 이점

  • 자바 패키지는 클래서와 인터페이스를 분류화 하는데 사용되어 패키지가 쉽게 유지될 수 있도록 한다
  • 자바 패키지는 이따가 알아 볼 접근 보호를 제공한다
  • 자바 패키지는 namespace 를 관리하여 이름 충돌을 제거한다 (변수명에 대한 충돌)

java 패키지에 대한 대략적인 그림

 

자바 패키지를 코드에서 정의해보자

 

인텔리제이에서 자바 프로젝트를 생성하면 아래 그림과 같은 구조로 구조가 잡힌다

여기서 com.live_study 가 이 프로젝트의 루트 패키지가 될 것이고 이 아래로 서브 패키지들을 생성해나가면 된다

 

예를 들어 shape 라는 패키지를 생성 후에 클래스를 만들어보았다

 

shape 패키지

해당 패키지에 파일을 생성하면 인텔리제이가 자동으로 패키지 이름을 명시해준다

위에 적어놨듯이 패키지 이름 패턴을 따르는 것을 볼 수 있다

▶ import 키워드

위에서 패키지에 대해서 알아봤다

그런데 내장 패키지든 우리가 만든 패키지든 있으니 써야하는데, 어떻게 쓸 수 있을까??

이럴 때에는 import 키워드를 사용하면 된다

 

import 키워드는 패키지, 클래스 또는 인터페이스를 불러올 때 사용한다

 

예를 들어 java.util 에 정의 된 ArrayList 를 불러오고 싶으면 다음과 같이 코드를 작성하면 된다

위의 코드는 다음과 같이 쓸 수도 있다 (많이 번거롭지만)

package 이름을 모두 명시해줘야해서 코드도 길어지고 불편하지만 서로 다른 패키지에서 같은 이름의 파일을 참조하게 되는 상황이 생긴다면 어쩔 수 없이 이런 방법을 사용해야 할 것이다

 

그리고 * (asterisk) 를 사용해서 해당 패키지에 있는 모든 것들을 import 할 수도 있다

♠ 클래스 내부에 있는 클래스들을 import 하는 방법

아래 코드처럼 하나의 클래스 안에 클래스들이 정의되어 있다고 가정해보자

그럴 때에는 다른 패키지를 불러오는 것과 비슷한 방법으로 저 내부 클래스들을 불러올 수 있다

 

import 할 때 주의사항

import 키워드는 반드시 package statement 다음, 타입 선언문 전에 나와야 한다(변수선언, 클래스 선언 등등)

 

♠ static import??

클래스 과제에서 알아봤듯이, 클래스 필드나 클래스 메소드를 사용하기 위해서는 클래스 이름을 사용하고자 하는 필드나 메소드 앞에 붙여서 사용해야했다

 

하지만 static import 를 사용하면 클래스 이름을 앞에 고정시킬 필요 없이 필드/메소드 이름으로만 사용할 수 있다

 

java.lang.Math 클래스에 있는 필드나 메소드는 모두 static 으로 되어있어서 여기 있는 요소들을 사용하기 위해서는

다음과 같이 코드를 작성할 수 있다

 

대강 피타고라스

하지만 Math 를 계속 앞에 붙이다 보면 귀찮기도 하고 코드가 길어질 수 있어서 Math 를 제거하고 순수 메소드만 사용하고 싶다면

import static 을 통하여 메소드를 import 하면 된다

import static 을 일일히 나열하기 귀찮다면 Math 내에 모든 요소를 import static 으로 불러오면 된다

※ import static 유의사항

코드가 길어지게 되면 사용하고 있는 static 필드/메소드가 어디에 정의되어 있는지 한 눈에 파악하기 힘들 수 있다

그리고 혹시나 실수로 같은 이름의 메소드를 정의해서 사용한다면 충돌이 일어날 수도 있을 것이다

하지만 적절하게 사용한다면 클래스 이름을 반복적으로 사용하지 않아도 되므로 코드의 가독성을 높일 수 있다

 

▶ 클래스 패스 (Class path)

클래스 패스(Class path) 는 JVM 또는 JAVA 컴파일러에게 사용자가 정의한 클래스나 패키지들의 위치를 명시해주는 매개변수이다

 

이 클래스 패스를 정해주는 방법은 CLASSPATH 환경변수를 통해서 지정해주는 방법과

커맨드 라인 툴(java, javac, javadoc 등등) 에 -classpath 옵션을 지정해줄 수 있다

 

클래스 패스를 왜 사용해야 하는걸까....?

이 이유는 JAVA의 실행과 관련이 있다

JAVA 프로그램이 실행될 때 JVM 이 lazy 하게 load 할 클래스들을 찾는다

(※ lazy?? => 클래스가 처음 사용 될 때에만 클래스의 바이트 코드를 load 하는 것을 뜻함)

 

그래서 클래스 패스는 JAVA에게 이 클래스들이 정의된 파일들을 file system 안에 어디서 찾아야 하는지 알려주는 역할을 한다

 

먼저 CLASSPATH 환경변수를 통해서 변수를 지정해주는 방법을 알아보자

 

▶ CLASSPATH 환경변수

CLASSPATH 환경 변수를 설정하기 위해서 윈도우에서는 cmd 를 실행, 맥이나 linux에서는 터미널을 실행시킨 후 다음 명령어를 입력한다

mac 터미널

※ 주의할 점

  • CLASSPATH 로 설정된 환경 변수는 -classpath 로 설정된 값에 덮어 씌어진다
  • 터미널이나 커맨드 창에서 설정한 환경 변수는 해당 터미널에서만 유효하다. 즉, 현재 터미널에서 CLASSPATH 환경 변수를 설정했다고 하더라도 다른 터미널에서는 적용되지 않는다

▶ -classpath 옵션

-classpath 옵션은 sdk tool (java, javac, javadoc 등) 과 함께 쓰여 커맨드 라인에서 자바 프로그램 실행 시 환경 변수를 제공하는 역할을 한다

 

 

▶ 접근지시자

JAVA 에는 다음과 같이 4가지의 접근 지시자가 있다

  • public
  • protected
  • private
  • default (no keyword)

● public

public 으로 선언된 클래스, 메소드, 생성자, 인터페이스는 다른 클래스에서 접근할 수 있다

특히 클래스 내부에 public 으로 선언된 필드, 메소드, block 은 모든 클래스에서 접근할 수 있다

 

하지만 현재 패키지에서 다른 패키지에 있는 특정 클래스에 접근하려면 public 으로 선언된 클래스를 import 해줘야 한다

 

● protected

슈퍼 클래스 내에 protected 선언된 변수, 메소드, 생성자는 이 슈퍼 클래스의 부분 생성자에서만 접근 가능하거나 동일 패키지 내의 클래스에서 접근 가능하다

 

protected 접근 지시자는 그 클래스와 연관되지 않은 클래스에서 필드/메소드를 사용하는 것을 방지해준다

 

● private

private 로 선언된 메소드, 변수, 생성자는 오직 선언된 클래스 내부에서만 접근할 수 있다

4가지 접근 지시자 중 가장 제한적인 접근 단계를 가지는 접근 지시자이다

 

특히 클래스와 인터페이스는 private 접근 지시자를 사용해서 선언될 수 없다

 

클래스 내부에 private 로 선언된 필드에 접근하기 위해서는 public 으로 선언된 getter 메소드를 통해서 접근할 수 있다

 

private 접근 지시자를 사용하는 주된 이유는 객체의 데이터를 캡슐화 하는 것과 외부로 부터 데이터를 숨기기 위함이다

 

● default (no keyword)

클래스, 변수(필드), 메소드, 생성자에 아무 접근 지시자 없이 선언하는 것을 기본 접근 지시자라고 한다

 

기본 접근 지시자로 선언되면 같은 패키지 내에 있는 다른 클래스에서 접근할 수 있다

 

참고로, 인터페이스 내에 필드는 암묵적으로 public static field 이며, 메소드는 public 이다.

 

※ 접근 지시자와 상속

상속된 메소드에 대해서는 다음과 같은 규칙들이 적용된다

  • 슈퍼 클래스 내에 public 으로 선언된 메소드는 부분 클래스에서도 public 이다
  • 슈퍼 클래스 내에 protected 로 선언된 메소드는 부분 클래스에서도 반드시 protected 이거나 public 이어야 한다.(private가 될 수 없다)
  • private 로 선언된 메소드는 상속되지 않기 때문에 규칙에 구애받지 않는다

 

[참고했던 사이트]

en.wikipedia.org/wiki/Classpath

www.w3schools.com/java/ref_keyword_package.asp

www.geeksforgeeks.org/packages-in-java/

docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html

en.wikibooks.org/wiki/Java_Programming/Keywords/import  

 

'공부 > whiteship-java' 카테고리의 다른 글

9주차: 예외 처리  (0) 2021.01.16
8주차: 인터페이스  (0) 2021.01.08
6주차: 상속  (0) 2020.12.24
5주차: 클래스  (0) 2020.12.19
4주차 과제: live-study 대시보드  (0) 2020.12.12