[Java] 3-2. 패키지(Pakage) / 제한자(Modifier)

루키·2024년 8월 5일

Java

목록 보기
10/10
post-thumbnail

1. Package란?

1-1. Package란?

  • Package(패키지) : 유사한 목적의 파일을 기준으로 폴더를 활용해서 관리하는 것을 의미합니다.
    패키지의 이름은 의미 있는 이름으로 만들고 .을 통해서 계층적으로 접근할 수 있습니다.

    • Fully Qualified Name : package name + class name
  • package의 선언

    • package <패키지 명>;
    • 주석, 공백을 제외한 첫 번째 문장에 하나의 패키지만 선언할 수 있습니다.
    • 모든 클래스는 하나의 패키지에 속합니다.
    • 패키지를 생략하게 되면 default package에 속하는데 이는 가급적 사용을 지양하고 있습니다.
  • Package Naming : 일반적인 package naming룰로는 소속.프로젝트.용도.~의 형태로 사용합니다

    • EX) com.companyName.hrm.common , com.companyName.hrm.service ...

1-2. 외부 Package Import하기

  • import : 다른 패키지에 선언된 클래스를 사용하기 위한 키워드입니다.

    • 패키지와 클래스 선언 사이에 위차하며, 패키지와 달리 여러 번 선언이 가능합니다.
  • import의 선언

    • import <패키지명>.<클래스명>; : 특정 클래스만 import 합니다.
    • import <패키지명>.*; : 특정 패키지에 있는 모든 클래스를 import 합니다.
      • 하위 패키지까지 import하지는 않습니다.
    • Ctrl + Shift + O 단축키를 활용하여 사용하고자 하는 클래스를 import할 수 있습니다.
  • import한 package의 클래스 이름이 동일하여 명확히 구분해야할 때는 클래스 이름 앞에 전체 패키지 명을 입력해서 명시해줍니다.

    • EX) java.util.List list = new java.util.ArrayList();
  • default import package : 별도로 import하지 않아도 기본적으로 import되는 패키지로 java.lang.*이 있습니다.

  • static import : 자주 사용되는 static member를 import 하여 static member의 이름만으로 접근 할 수 있습니다.

    • Ex) import static java.lang.System.out; out.println("static import");
    • 주로 단위 테스트에 필요한 항목들을 사용할 때 static import를 활용합니다.

<일반적인 클래스 레이아웃>

 package structure;                                     // 패키지 선언부
 
 import java.io.*;                                      // 외부 패키지 import
 
 public class ClassStructure {                          // class 선언부
 
     String name;                                       // 멤버 변수
     int age;
     
     {name = "루키";}                                   // 초기화 블록
     
     public ClassStructure(String name, int age) {     // 생성자
         this.name = name;
         this.age = age;
     }
     
     public void setName(String name) {                // 멤버 메서드
         this.name = name;
     }
     
     public static void main(String[] args) {
         ClassStructure cs = new ClassStructure("hong", 10);
     }
}

2. Modifier란?

  • 제한자는 클래스, 변수, 메서드 선언부에 함께 사용되어 부가적인 의미를 부여해줍니다. 크게 접근 제한자와 그 외의 제한자로 분류할 수 있습니다.
    • 하나의 대상에 여러 제한자를 조합해서 사용할 수 있고, 순서는 무관합니다.
    • 접근 제한자는 하나만 사용할 수 있고, 일반적으로 접근 제한자를 맨 앞에 붙여서 사용합니다.

2-1. 접근 제한자

제한자용도------------접근 가능 범위-----------------------------------------------
클래스생성자멤버같은 클래스같은 패키지다른 패키지의 자손 클래스전체
publicOOOOOOO
protectedOOOOO
package(default)OOOOO
privateOOO

method overriding을 할 때, 부모의 제한자 범위와 같거나 넓은 범위로만 사용이 가능합니다.

2-2. 그 외 제한자

  • static : 클래스 레벨의 요소 설정
  • final : 요소를 더 이상 수정할 수 없게 함
  • abstract : 추상 메서드 및 추상 클래스 작성
  • synchronized : 멀티 스레드에서의 동기화 처리

final

  • 더 이상 바뀔 수 없음을 나타내는 제한자로, final class는 더 이상 확장 불가능(상속 금지 -> 오버라이드 방지)하고, final method는 더이상 재정의(Overriding) 할 수 없도록, final variable은 더 이상 값을 바꿀 수 없도록 설정합니다.

    Blank final : 값이 할당되지 않은 final 멤버 변수

    • final 멤버 변수에 초기 값이 할당되어버리면 모든 객체는 같은 값을 사용해야합니다.
    • 객체가 생성되면 값을 변경할 기회가 없기 때문에 반드시 생성자에서 1회 초기화 해줘야합니다.

static final : final만 있으면 객체마다 갖는 값으로 공용성이 없습니다. 따라서 진정한 상수로 만들어주기 위해서는 static 키워드를 붙여 모두가 공용할 수 있도록 해줘야합니다.

2-3. Sealed Class

  • 봉인된 클래스로 특정 클래스에게만 상속이 가능하도록 하는 키워드입니다.
  • 상속 계층 내에서 엄격한 제어를 통해
    • 프로그램의 구조를 명확하게 유지하고, 의도치 않은 상속으로 인한 복잡성과 혼란을 방지합니다.
    • 명확한 역할과 직무 분류가 중요한 개념에서 주로 사용됩니다.

작성법

  • 클래스(인터페이스)에 sealed 키워드를 사용하고, 상속(구현)을 허락하는 클래스를 permits 뒤에 나열해줍니다.
  • 구현 클래스는 다음 키워드 중 하나를 사용해야합니다.
    • sealed : 여전히 봉인된 클래스로 추가적으로 permits로 하위 클래스를 나열해야합니다.
    • final : 더 이상 상속 받을 수 없는 클래스로 마지막을 나타냅니다.
    • non-sealed : 봉인이 해제된 클래스로 다시 자유롭게 상속할 수 있습니다.

2-4. Singleton 디자인 패턴

  • 데이터 은닉과 보호를 위해서 캡슐화를 진행할 수 있습니다. 캡슐화는 외부에서 데이터에 접근할 수 없도록 하는 것으로, 멤버 변수를 private 제한자로 설정하여 접근을 막고, 공개되는 메서드(getter / setter)를 통해서만 변수를 제어할 수 있도록 설정합니다.
  • 변수는 메서드로 제어할 수 있지만, 변수 생성 자체를 제한하기 위해서는 Singleton 디자인 패턴을 활용할 수 있습니다.

Singleton

객체를 계속 생성/삭제하는데 많은 비용이 들어서 재사용이 유리할 때 이러한 singleton 디자인 패턴을 사용합니다.
객체에 수정가능한 멤버 변수가 없고, 기능만 있어서 구별할 필요가 없는 객체를 stateless한 객체라고 부르고 이러한 객체를 생성할 때에도 singleton 패턴을 사용합니다.

class SingletonClass{
    private static SingletonClass instance = new SingletonClass();
    private SingletonClass() {}
    public static SingletonClass getInstance() {
        return instance;
    }
}

위와 같이 생성자를 private로 제한하여 객체 생성을 제한하고, 객체 생성은 instance를 통해서만 가능하도록 하고, instance는 외부에서 접근할 수 있도록 static 키워드를 사용합니다. 해당 클래스에 접근하기 위해서는 public 메서드인 getter(getInstance)를 통해서만 접근이 가능하도록 구현합니다. 객체를 다시 생성할 일은 없으므로 setter는 필요하지 않습니다.

profile
주니어 FrontEnd 개발자가 되기 위한 기록

0개의 댓글