Dev.Std

접근 제어자 (Access Modifier) 본문

📂Language/Java

접근 제어자 (Access Modifier)

expr01 2024. 4. 7. 23:01

접근 제어자(Access Modifier)

 객체 지향에서 정보 은닉은 사용자가 굳이 알 필요 없는 정보는 사용자에게 숨겨야 한다는 개념이다. 자바에서는 이러한 정보 은닉을 위해 접근 제어자(Access Modifier)를 제공하고 있다. 

 자바에서는 다음과 같은 4가지의 접근 제어자를 제공한다.

  • private
  • default
  • protected
  • public

private

접근 제어자가 private로 설정되었다면 pivate이 붙은 변수나 메서드는 해당 클래스 내에서만 접근을 허용한다.

private 멤버 접근 영역

package oop;

public class Student {
    // private 접근 제어자로 선언된 변수
    // 해당 클래스 내에서만 접근 가능하도록 제한
    // 아래에서 public 메서드를 이용해서 private 변수에 접근하도록 함
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getter & Setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

oop/Student.java

package oop;

public class AccessModifier {
    public static void main(String[] args) {
        Student student = new Student("John", 20);

        student.setName("Alice");
        student.setAge(25);

        System.out.println("Name: " + student.getName());
        System.out.println("Age: " + student.getAge());
    }
}

oop/AccessModifier.java

Name: Alice
Age: 25

 Student 클래스에 private로 선언된 변수는 다른 클래스에서 함부로 접근할 수 없지만 같은 클래스에서만 접근할 수 있다는 성질을 이용해서 public 메서드를 통해 간접적으로 접근하고 있다.

 이렇게 private 멤버 변수에 접근하고 수정하기 위해 사용되는 메서드를 GetterSetter라고 한다. Getter는 private 멤버 변수의 값을 반환하고, Setter는 private 멤버 변수의 값을 설정하는 메서드이다.

 Getter와 Setter의 주요 목적은 정보 은닉(information hiding)캡슐화(encapsulation)를 실현하는 것이지만, 실제로는 그다지 정보 은닉과 캡슐화를 실현하고 있지 않다. 그렇기에 Getter와 Setter를 통해 private 멤버 변수에 접근하는 것을 지양해야 한다는 말이 많은 것 같다. 이 Getter와 Setter에 대한 부분은 따로 다시 다루어보아야겠다.


default

사용자가 접근 제어자를 따로 지정하지 않으면 default 접근 제어를 가지게 된다. default 접근 제어를 가진 멤버는 동일한 패키지 내에서 접근이 가능하다.

default 멤버 접근 영역

package oop;

public class Student {
    // default 접근 제어자를 가지는 변수
    String name;

    public Student(String name) {
        this.name = name;
    }

    public void display() {
        System.out.println("Name : " + name);
    }
}

oop/Student.java

package oop;

public class AccessModifier {
    public static void main(String[] args) {
        Student student = new Student("John");

        student.display();
    }
}

oop/AccessModifier.java

Name : John

Student 클래스와 AccessModifier 클래스의 패키지는 모두 oop로 동일하다. 따라서 Student 클래스에서 default로 선언된 name 변수에 접근할 수 있다.


protected

부모 클래스와 관련된 접근 제어자이다. protected 멤버는 부모 클래스에 대해서 public 멤버처럼 취급하며, 외부에서는 private 멤버처럼 취급된다.

protected 멤버 접근 영역

package oop;

public class Student {
    // default 접근 제어자를 가지는 변수
    protected String name;

    public Student(String name) {
        this.name = name;
    }
    public void display() {
        System.out.println("Name : " + name);
    }
}

oop/Student.java

package oop2;

import oop.Student;

public class HighSchoolStudent extends Student {
    public HighSchoolStudent(String name) {
        super(name);
    }

    // 부모 클래스인 Student의 protected 멤버에 접근하여 출력하는 메서드
    public void displayParentName() {
        System.out.println("Parent's Name (accessed from child class): " + name);
    }
}

oop2/HighSchoolStudent.java

package oop;

import oop2.HighSchoolStudent;

public class AccessModifier {
    public static void main(String[] args) {
        HighSchoolStudent student = new HighSchoolStudent("Alice");

        student.displayParentName();
    }
}

oop/AccessModifier.java

Parent's Name (accessed from child class): Alice

 Student를 상속한 HighSchoolStudent 클래스의 패키지는 oop2로 Student 클래스의 패키지인 oop와 다르다. 하지만 Student 클래스의 name이 protected로 접근 제어자를 가지고 있기 때문에 HighSchoolStudent 클래스에서 접근할 수 있다.

 여기서 super 키워드는 부모 클래스를 명시적으로 호출하는 역할을 한다. 위의 코드에서는 부모 클래스의 생성자를 호출하는 역할을 하고 있다. main 함수에서 Alice라는 문자열을 HighSchoolStudent 생성자에 넘기면 해당 생성자에서 부모 클래스의 Student 생성자에 Alice라는 문자열을 넘기면서 부모 클래스의 생성자를 호출하게 된다. 이때 protected로 선언된 변수에 접근할 수 있는 것이다.


public

public 접근 제어자가 붙은 변수나 메서드는 어떤 클래스에서도 접근이 가능하다.

public 멤버 접근 영역

 public 접근 제어자는 별다른 부연설명 없이 단순히 모든 클래스에서 접근 가능함을 알고 있으면 될 것 같다.

 

References

https://www.tcpschool.com/java/java_modifier_accessModifier