[JAVA 기초] 자바 제어자
제어자란 클래스나 멤버의 사용을 제어하기 위해 사용된다. 제어자의 종류에는 외부에서 접근하는 것을 막는 접근제어자와 클래스 멤버를 의미하는 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)라고 한다. 만약 셋터를 설정하지 않았다면 데이터의 조회만 가능한 클래스가 된다.