Access Modifier

KKH_94·2023년 6월 7일
0

JAVA

목록 보기
12/36

클래스 접근 제어자

Access modifier는 프로그래밍 언어에서 클래스, 변수, 메서드 등의 멤버에 대한 접근 권한을 제어하는 데 사용되는 키워드입니다.

이러한 접근 제어는 객체 지향 프로그래밍에서 캡슐화, 정보 은닉 및 보안을 달성하는 데 중요합니다.

일반적으로 다음과 같은 네 가지 주요한 접근 제어 수준이 있습니다.

  1. Public

public으로 표시된 멤버는 모든 외부 클래스에서 직접 액세스할 수 있습니다. 즉, 해당 멤버는 어디에서나 호출하고 사용할 수 있습니다.

  1. Private

private으로 표시된 멤버는 동일한 클래스 내에서만 액세스할 수 있습니다. 외부 클래스나 다른 클래스에서는 직접 액세스할 수 없으며, 해당 클래스의 내부에서만 사용됩니다.

  1. Protected

protected로 표시된 멤버는 동일한 패키지 내의 클래스와 해당 클래스를 상속한 하위 클래스에서 액세스할 수 있습니다. 다른 패키지 내의 클래스에서는 직접 액세스할 수 없습니다.

  1. Package-private(default)

액세스 제한자를 지정하지 않은 경우, 멤버는 동일한 패키지 내의 다른 클래스에서 액세스할 수 있습니다. 하지만 다른 패키지에서는 액세스할 수 없습니다.

이러한 접근 제어 수준을 사용하여 클래스의 내부 구현 세부 정보를 숨기고, 캡슐화를 유지하며, 필요한 경우에만 외부에 공개할 수 있습니다. 이는 안전성, 유지 관리성 및 코드 재사용성을 향상시키는 데 도움이 됩니다.

  • Within Package : 동일한 패키지에 있는 다른 일반 클래스

  • Global : 외부 패키지에 있는 일반 클래스



PRIVATE : 같은 package나 다른 package에 있어도 모두 참조 불가.

PROTECTED : 다른 package에서 상속을 받으면 참조 가능.

DEFAULT(package private) : 같은 package에서는 참조 가능한데, 다른 package에서는 참조 불가.

PUBLIC : 같은 package나 다른 package 모두 자유롭게 참조 가능.

* interface는 defalut값이 public. 

클래스의 메서드에 접근 제어자를 선언하지 않으면, 기본적으로 해당 메서드는 package-private 접근 제어자가 적용됩니다.

package-private 접근 제어자는 해당 클래스와 동일한 패키지 내에서만 접근할 수 있는 제한을 가지는 접근 제어자입니다. 다른 클래스나 패키지에서는 해당 메서드에 접근할 수 없습니다.

즉, 클래스의 메서드에 접근 제어자를 명시하지 않을 경우, 컴파일러는 해당 메서드를 package-private 접근 제어자로 간주합니다.

이는 같은 패키지 내의 다른 클래스에서는 접근할 수 있지만, 다른 패키지에 속한 클래스에서는 접근할 수 없다는 것을 의미합니다.

다음은 접근 제어자를 명시하지 않은 클래스의 메서드의 예시 코드입니다:

package com.example;

public class MyClass {
    void myMethod() {
        System.out.println("This is a package-private method.");
    }
}

위의 코드에서 MyClass는 myMethod()라는 메서드를 접근 제어자를 명시하지 않고 선언합니다. 이 경우 컴파일러는 해당 메서드를 package-private 접근 제어자로 간주하며, 같은 패키지 내의 다른 클래스에서는 myMethod()에 접근할 수 있습니다. 그러나 다른 패키지에 속한 클래스에서는 myMethod()에 접근할 수 없습니다.

따라서, 클래스의 메서드에 접근 제어자를 선언하지 않으면, 해당 메서드는 package-private 접근 제어자가 적용되어 같은 패키지 내의 클래스에서만 접근할 수 있는 메서드로 처리됩니다.

※클래스의 필드는 일반적으로 private, protected, public 접근 제어자 중 하나로 선언해야 합니다.

인터페이스 접근 제어자

default 접근 제어자는 인터페이스의 메서드에 적용되는 접근 제어자입니다.

클래스의 필드를 default 접근 제어자로 선언할 수 있는 경우는 인터페이스에서의 경우뿐입니다. 클래스의 필드는 일반적으로 private, protected, public 접근 제어자 중 하나로 선언해야 합니다.

인터페이스에서 메서드를 선언할 때 접근 제어자를 명시하지 않으면, 기본적으로 해당 메서드는 public 접근 제어자가 적용됩니다.

인터페이스는 기본적으로 외부에서 해당 인터페이스의 메서드를 호출하기 위해 설계되었기 때문에, 인터페이스의 메서드는 기본적으로 public으로 간주됩니다.

이는 인터페이스를 구현한 클래스에서 메서드를 오버라이딩하고 호출할 수 있도록 하는데 중요한 역할을 합니다.

따라서, 인터페이스에서 메서드를 선언할 때 접근 제어자를 명시하지 않으면, 컴파일러는 해당 메서드를 public으로 간주합니다.

다음은 접근 제어자를 명시하지 않은 인터페이스의 예시 코드입니다:

interface MyInterface {
    void myMethod(); // 접근 제어자를 명시하지 않음 (기본적으로 public)
}

class MyClass implements MyInterface {
    public void myMethod() {
        System.out.println("MyMethod가 호출되었습니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass myObject = new MyClass();
        myObject.myMethod(); // "MyMethod가 호출되었습니다." 출력
    }
}

위의 코드에서 MyInterface는 myMethod()라는 메서드를 선언합니다. 여기서는 접근 제어자를 명시하지 않았으므로, 해당 메서드는 기본적으로 public으로 간주됩니다.

MyClass 클래스는 MyInterface를 구현하여 myMethod()를 오버라이딩하고, 메서드를 구체적으로 구현합니다.

Main 클래스에서는 MyClass의 인스턴스를 생성하고, myMethod()를 호출하여 출력 결과를 확인합니다.

출력 결과는 다음과 같습니다:

MyMethod가 호출되었습니다.

이를 통해 인터페이스에서 메서드를 선언할 때 접근 제어자를 명시하지 않으면, 해당 메서드는 기본적으로 public으로 간주되어 외부에서 호출할 수 있는 메서드로 처리됨을 알 수 있습니다.

인터페이스의 추상 메서드를 public으로 선언하면 모든 구현 클래스에서 반드시 해당 메서드를 구현해야 합니다.

반면에 default로 선언하면 해당 메서드에 대한 기본 구현을 제공하면서도 구현 클래스에서 선택적으로 오버라이딩할 수 있습니다.

public으로 선언된 추상 메서드는 다음과 같은 특징을 가지고 있습니다:

모든 구현 클래스에서 해당 메서드를 오버라이딩하여 구현해야 합니다.

인터페이스를 구현하는 모든 클래스에서 해당 메서드의 공개적인 API를 제공합니다.
반면에 default로 선언된 메서드는 다음과 같은 특징을 가지고 있습니다:

인터페이스에서 해당 메서드의 기본 구현을 제공합니다.

구현 클래스에서는 해당 메서드를 오버라이딩하지 않아도 됩니다.

구현 클래스에서 선택적으로 해당 메서드를 오버라이딩하여 기본 구현을 변경할 수 있습니다.

아래의 코드는 public과 default로 선언된 추상 메서드의 차이를 보여줍니다:

interface Printable {
    public void print(); // public으로 선언된 추상 메서드

    default void defaultPrint() { //interface에서만 defalut 키워드 적용 가능.
        System.out.println("기본적인 출력입니다.");
    }
}

class Printer implements Printable {
    public void print() {
        System.out.println("프린터에서 출력합니다.");
    }

    public void defaultPrint() {
        System.out.println("프린터에서 재정의된 출력입니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print(); // "프린터에서 출력합니다." 출력
        printer.defaultPrint(); // "프린터에서 재정의된 출력입니다." 출력

        Printable printable = new Printer(); //interface로 참조변수 
        // 이 방식을 가장 많이 씀 // 객체가 뭔자 알수없어서 interface를 씀. loose cuplic. 느슨한 결합.
        printable.print(); // "프린터에서 출력합니다." 출력
        printable.defaultPrint(); // "프린터에서 재정의된 출력입니다." 출력
    }
}

위의 코드에서 Printable 인터페이스는 public으로 선언된 print() 메서드와 default로 선언된 defaultPrint() 메서드를 가지고 있습니다.

Printer 클래스는 Printable 인터페이스를 구현하고, 각 메서드를 구체적으로 구현합니다.

Main 클래스에서는 Printer 클래스의 인스턴스를 생성하고, print()와 defaultPrint() 메서드를 호출합니다.

이를 통해 public 메서드와 default 메서드 모두 사용됨을 확인할 수 있습니다.

출력 결과는 다음과 같습니다:

프린터에서 출력합니다.
프린터에서 재정의된 출력입니다.
프린터에서 출력합니다.
프린터에서 재정의된 출력입니다
profile
_serendipity

0개의 댓글