본문 바로가기
Java/Java 기초문법

[JAVA 기초] 자바 제어자

by dev수니 2021. 3. 12.
반응형

 

 

 

제어자란 클래스나 멤버의 사용을 제어하기 위해 사용된다. 제어자의 종류에는 외부에서 접근하는 것을 막는 접근제어자와 클래스 멤버를 의미하는 static, 상수를 만들거나 상속을 종결시키는 final 등이 있다.

 

 


 

 

① static
필드의 선언 또는 메서드의 정의문 앞에 "static" 키워드를 붙이면 클래스변수, 클래스메서드가 되어 클래스 멤버가 된다.

클래스 멤버는 처음 클래스가 메모리에 로드될 때 생성되기 때문에 인스턴스를 생성하지 않아도 사용 가능하다.

 

 

 


② final
- 변수 앞 : 변수가 상수가 된다. 값을 더이상 변경할 수 없어진다.
(ex) final double pi = 3.14;  // 상수
     // pi += 1;   // ERR.  // 4.14
- 메서드 앞 : 메서드 오버라이드가 금지된다.
- 클래스 앞 : 상속이 금지된다.

 

 

 

 

③ 접근 제어자(Access Modifier)

접근 제어자는 외부에서 접근할 수 있는 정도와 범위를 정해준다.

접근 제어자로는 허용 범위가 넓은 순서대로 public, protected, default, private가 있다. 여기서 default는 아무런 접근 제어자를 자성하지 않았을 경우를 말한다.

public : 접근제한 없음.
protected : 같은 패키지 내에서와 자손 클래스에서 접근 가능
default : 같은 패키지 내에서만 접근 가능
private : 같은 클래스 내에서만 접근 가능

가시성(visibility)의 범위

public > protected > (default) > private
public : 가시성의 범위가 제일 넓음. --> "제한하지 않음."
(default) : 해당 패키지 안에서만 보임. --> "다른 패키지에서는 볼 수 없음."
private : 해당 클래스 안에서만 보임. --> "클래스 밖에서는 절대로 볼 수 없음."
참고로, protected = "(default) + Child"

 

- 클래스 앞에 붙는 2가지: public, (default)
- (default) 접근제어자를 사용한 클래스 또는 클래스의 멤버들은
해당 패키지를 벗어나면, 사용할 수 없음

 

 


 

Ex 예제 1.

다음은 final 클래스, static 변수, 상수, static메서드 ,final 메서드를 사용한 예제이다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package java_practice;
 
final class Final {
    static int a = 1;
    final static int b = 3;
    static int sum() {
        return a+b;
    }
}
 
class ParentA {
    final void finalmethod () {
        System.out.println("finalmethod 호출됨.");
    }
}
 
//class ChildFinal extends Final{    }    // final 클래스 상속 불가
 
class ChildParentA extends ParentA {
//    void finalmethod () {    }        // final 메서드 오버라이딩 불가
}
 
public class FainalClass {
 
    public static void main(String[] args) {
        Final.a = 2;    // Final클래스 a값 = 2
//        Final.b = 6;    // final 변수(상수) 값 재정의 불가
        System.out.println(Final.sum());  // 2+3= 5
        
        ChildParentA c1 = new ChildParentA();
        c1.finalmethod();
    }
}
 
cs

 

줄 17에서 final클래스가 상속이 불가한 것을 볼 수 있으며 줄20에서 fainal메서드가 오버라이딩이 불가한 것을 볼 수 있다. 또한 줄27에서 상수의 값을 변경할 수 없는 모습도 확인할 수 있다.

 

따라서 출력 결과는 다음과 같다.

5
finalmethod 호출됨.

 

 

 

 

 

 

Ex 예제 2.

다음은 public을 이용한 예제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package java_practice;
 
class User{
    public String name;
    public int age;
    User(String name, int age){        // 매개변수가 있는 생성자
        this.name = name;
        this.age = age;
    }
}
 
public class PublicClass {
 
    public static void main(String[] args) {
 
        User user1 = new User("철수"20);        // 인스턴스 생성
        User user2 =  new User("영희"19);        // 인스턴스 생성
        
        System.out.println(user1.name + "의 나이는 : " + user1.age);
        System.out.println(user2.name + "의 나이는 : " + user2.age);
 
        user1.age = 99;            // user1인스턴스의 나이를 99로 변경
        user1.name = "말순";    // user1인스턴스의 이름을 "말순"으로 변경
        
        System.out.println(user1.name + "의 나이는 : " + user1.age);
        System.out.println(user2.name + "의 나이는 : " + user2.age);
    }
}
cs

출력결과

철수의 나이는 : 20
영희의 나이는 : 19
말순의 나이는 : 99
영희의 나이는 : 19

public으로 선언된 이름과 나이는 외부에서 자유롭게 접근할 수 있는 변수이다.

 

 

 

 

 

 

 

Ex 예제 3.

다음은 private을 이용한 예제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package java_practice;
 
class UserA{
    private String name;        // private 으로 직접 접근 제한
    private int age;
    UserA(String name, int age){    // 매개변수를 가진 생성자
        this.name = name;
        this.age = age;
    }
    
    public void setName(String name) {    // setName 메서드를 이용해 값 설정
        this.name = name;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public String getName() {        //  getName 메서드를 이용해 값 반환
        return name;
    }
    public int getAge() {
        return age;
    }
}
 
public class PrivateClass {
 
    public static void main(String[] args) {
        UserA user1 = new UserA("철수"20);    // 인스턴스 생성
        UserA user2 = new UserA("영희"19);    // 인스턴스 생성
        
//      user2.age = 99;    // 에러 private 변수 직집적 접근 불가
 
        user2.setAge(50);  // setAge 메서드를 이용해 간접적 접근
        
        System.out.println(user1.getName() + "의 나이는 : " + user1.getAge());
        System.out.println(user2.getName() + "의 나이는 : " + user2.getAge());
    }
}
cs

 

이 코드에서는 객체의 이름과 나이의 접근 제어자를 private로 설정한다. 따라서 줄33과 같은 접근은 에러가 발생한다.

 

대신에 클래스 내부에 getName, setName 메서드를 구현해서 간접적으로 값에 접근할 수 있도록 한다. 이러한 방식으로 구현하면 데이터의 안정성이 확보된다.

 

이름을 반환하는 get형식의 메서드를 게터(getter)라고 하고 변수의 값을 설정하는 set형식의 메서드를 셋터(setter)라고 한다. 만약 셋터를 설정하지 않았다면 데이터의 조회만 가능한 클래스가 된다.

 

 

 

 

 

 

 

 

반응형

댓글