본문으로 바로가기

접근제어자란(Access Modifier)?

 

자바에는 클래스에 대한 접근을 제한하는 문법이 있는데 이를 접근제어자(Access Modifier)라고 한다.

접근 제어자는 멤버변수들의 고유성격을 파악하여 외부에서 접근해야할 바운더리를 성격에 맞게 오픈해줘야 사용한다. 

접근제어자는 다음과 같이 4가지가 있다.

  • private : 자기 자신 클래스에서만 접근이 가능함.
  • default : 특정 제어자를 선언하지 않는경우 default 셋팅이 되며 동일 패키지에서 사용이 가능하다.
  • protected : 동일패키지, 자식 클래스에서 사용 가능하다.
  • public : 접근제한이 없다.

 

접근 제한의 범위는 다음과 같다.

public > protected > default > private

 

일반적으로 개발을 진행하다보면 알겠지만, public private 가장 많이 사용한다. private으로 멤버변수 접근을 제한하고 public 메소드로 해당 멤버변수에 접근하여 값을 수정하는것이 기본 골격이기 때문.

 

 

1. private, public

 

private선언된 변수 혹은 메소드는 해당 클래스에서만 접근이 가능하다. public으로 선언된 변수 혹은 메소드는 어디서든 접근이 가능하다. 그래서 2가지는 거의 같이 쓰인다. 다음 소스를 보자

 

human.java

1
2
3
4
5
6
7
8
9
package exAccessModifier;
 
public class human {
    private String sex = ""
    
    public String getSex() {
        return this.sex;
    }
}
 

 

 

woman.java

1
2
3
4
5
6
7
8
9
10
11
package exAccessModifier;
 
public class woman {
 
    public static void main(String[] args) {
        human female = new human();
 
        female.sex = "woman";   // sex변수는 private접근제어자로 선언되었기때문에 바로 접근이 불가능하다.
        System.out.println("I am a " + female.getSex());
    }
}
 
 

 

woman.java 실행하면 "The field human.sex is not visible"에러가 발생한다. human 멤버변수 sex(성별)변수에 접근할 없어서 발생하는 에러이다. 일반적으로 이렇게 private으로 지정된 변수는 public메소드를 통해 접근하게 한다.

수정된 다음 소스를 확인하자.

 

human.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package exAccessModifier;
 
public class human {
    private String sex = ""
    
    //public으로 지정된 메소드를 통해 멤버변수의 값을 지정할 수 있게 해준다.
    public void setSex(String sex) {
        this.sex = sex;
    }
 
    public String getSex() {
        return this.sex;
    }
}
 
 

 

 

woman.java

1
2
3
4
5
6
7
8
9
10
11
package exAccessModifier;
 
public class woman {
 
    public static void main(String[] args) {
        human female = new human();
 
        female.setSex("woman");        //메소드를 통해 값을 전달한다.
        System.out.println("I am a " + female.getSex());
    }
}
 
 

 

 

결과

I am a woman

 

human 클래스 setSex(String sex) 통하여 멤버변수 sex 접근하여 값을 대입할 있다. 이런식으로 값을 지정함에 있어 의문점이 있다. 객체를 생성하고 바로 멤버변수에 접근하여 값을 지정하면 소스도 간결해지고 편하지 않는가? 하지만 예외치 못한 값에 대한 예외처리를 없다. 그래서 public메소드를 지정하여 예외처리를 있는 것이다. human클래스의 setSex메소드를 다음과 같이 사용할 있다.

 

1
2
3
4
5
6
7
public void setSex(String sex) {
    if!("man".equalsIgnoreCase(sex) || "woman".equalsIgnoreCase(sex)) ) {
        this.sex = "what is your sex..??";
    }else {
        this.sex = sex;
    }
}
 
 

 

위와 같이 특정 값에 대한 예외처리를 있다.

 

 

 

2. default

 

default접근제어자는 동일한 패키지 영역에서의 접근 가능하다.

 

Car.java

1
2
3
4
5
package exAccessModifierDefault;
 
public class Car {
    String name = "";
}
 
 

 

main.java

1
2
3
4
5
6
7
8
9
10
11
12
package exAccessModifierDefault;
 
public class main {
 
    public static void main(String[] args) {
        Car sonata = new Car();
        sonata.name = "sonata";
        
        System.out.println(sonata.name);
    }
 
}
 
 

 

exAccessModifierDefault 패키지내 main클래스에서 car클래스의 객체를 생성하고 name멤버변수에 접근할 있다.

 

 

 

3. protected

 

default접근자와 마찬가지로 protected 동일 패키지내에서 접근이 가능하다. 하지만 default 차이점이 있다면 상속관계에서(파생클래스)에서 접근이 가능하다는 점에서 default보다 접근범위가 넓다.

 

car.java

1
2
3
4
5
6
7
8
9
package exProtected.exam1;
 
public class car {
    protected String name = "";
    
    protected void setName(String name) {
        this.name = name;
    }
}
 
 

 

 

sonata.java

1
2
3
4
5
6
7
8
9
10
package exProtected.exam2;
 
 
public class sonata extends car {
    public void print() {
        this.name = "sonata";
        System.out.println(this.name);
    }
}
 
 

 

 

main.java

1
2
3
4
5
6
7
8
9
package exProtected.exam2;
 
public class main{
 
    public static void main(String[] args) {
        sonata son = new sonata();
        son.print();
    }
}
 
 

 

 

sonata 클래스와 car 클래스는 위치하는 패키지는 다르지만 sonata클래스는 car클래스 상속받음으로써 car클래스의 멤버변수에 접근할 있다.