Java

정보 은닉

안루피 2023. 10. 3. 13:20
728x90

접근 제어자 살펴보기

 

객체 지향 프로그램에서는 예약어를 사용해 클래스 내부의 변수나 메서드, 생성자에 대한 접근 권한을 지정할 수 있다. 이러한 예약어를 '접근 제어자(access modifier)'라고 한다. Student.java 코드의 모든 변수에는 public 예약어가 있다. public이라고 선언한 변수나 메서드는 외부 클래스에서 접근이 가능하며 외부 클래스가 사용할 수 있다는 뜻이다. 반대로 접근 제어자를 private으로 선언한 변수나 메서드는 외부 클래스에서 사용할 수 없다.

 

다음 예제에서 변수를 private으로 선언하면 결과 값이 어떻게 바뀌는지 알아보자.

 

package hiding;

public class Student {
	int studentID;
	//studentName 변수를 private으로 선언 
	private String studentName;
	int grade;
	String address;
	
	public String getStudentName() {
		return studentName;
	}
	
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
}

 

앞 예제에서 studentName 변수를 private으로 바꿔보았다. 그리고 파일을 저장한다.

 

 

코드를 수정한 후 저장하고 나서 Student.java 파일의 실행 클래스인 SrudentTest.java 파일을 보니 오류가 발생한다. 그 이유는 무엇일까? studentName 변수의 접근 제어자가 public일때는 외부 클래스인 StudentTest.java 클래스에서 이 변수에 접근할 수 있었지만, private으로 바뀌면거 외부 클래스의 접근이 허용되지 않기 때문이다. 

 

 

get(), set() 메서드

 

그러면 private으로 선언한 studentName 변수를 외부 코드에서 사용하려면 어떻게 해야 할까? studentName 변수를 사용할 수 있도록 public 메서드를 제공해야 한다. public 메서드가 제공되지 않는다면 studentName 변수에 접근할 수 있는 방법은 없다. 이때 사용할 수 있는 것이 바로 get(), set() 메서드이다. 

 

* 값을 얻는 get() 메서드를 getter, 값을 지정하는 set() 메서드를 setter라고도 부른다.

 

 

package hiding;

public class Student {
	int studentID;
	//studentName 변수를 private으로 선언 
	private String studentName;
	int grade;
	String address;
	
	//private 변수인 studentName에 접근해 값을 가져오는 public get() 메서드 
	public String getStudentName() {
		return studentName;
	}
	
	////private 변수인 studentName에 접근해 값을 지정하는 public set() 메서드
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
}

 

학생 이름을 받아오거나 지정할 수 있도록 getStudentName() 메서드와 setStudentName() 메서드를 추가하였다. 

 

이클립스에서는 모든 멤버 변수에 대해 get 메서드와 set 메서드를 자동으로 만들 수 있는 기능을 제공한다. 이클립스 편집기 창의 멤버 변수를 선언한 클래스 내부에서 오른쪽 마우스를 클릭하고 [Source -> Generate Getters and Setters...] 메뉴를 클릭하면 아래와 같은 창이 뜬다. 이 중 get(), set() 메서드를 추가하고 싶은 멤버 변수를 선택하고 아래쪽의 [OK]를 누르면 해당 변수의 get(), set() 메서드가 생성된다. 

 

 

다음과 같이 studentTest.java 파일을 수정한다.

 

package hiding;

public class StudentTest {

	public static void main(String[] args) {
		Student studentLee = new Student();
		//studentLee.studentName = "이건희"; //오류 발생
		//setStudentName() 메서드를 활용해 private 변수에 접근 가능 
		studentLee.setStudentName("이건희");
		
		System.out.println(studentLee.getStudentName());

	}

}

 

studentName 멤버 변수에 이름 값을 직접 대입하는 것이 아니고 setStudentName() 메서드를 활용하여 값을 대입할 수 있다. 즉 외부 클래스에서 private 변수에 직접 접근할 수는 없지만, public 메서드를 통하면 private 변수에 접근할 수 있다.

 

정보 은닉이란?

 

변수를 public으로 선언하는 것과 변수를 private으로 선언하고 나서 그 변수를 사용할 수 있도록 public 메서드를 제공하는 것의 차이는 무엇일까? 어차피 변수에 접근하는 것은 마찬가지인데 말이다. 다음 예제를 생각해보자.

 

public class MyDate {
	public int day;
	public int month;
	public int year;
}

 

 앞 코드에서 MyDate 클래스를 보면 MyDate 클래스의 day, month, year를 모두 public으로 선언했다. 따라서 외부 클래스에서 MyDate를 사용할 때 값을 마음대로 넣을 수 있다. 그리고 이 클래스를 사용한 다음 코드를 보면 2월은 28이나 29일까지인데 31일로 대입되었다. 

 

package test;

public class MyDateTest {

	public static void main(String[] args) {
		MyDate date = new MyDate();
		date.month = 2;
		date.day = 31;
		date.year = 2023;
	}
}

 

즉 클래스의 멤버 변수를 public으로 선언하면 접근이 제한되지 않으므로 정보의 오류가 발생할 수 있다. 이런 경우에는 오류가 나더라도 그 값이 해당 변수에 대입되지 못하도록 다음과 같이 변수를 private으로 바꾸고 public 메서드를 별도로 제공해야 한다. 

 

public class MyDate {
	private int day;
	private int month;
	private int year;
	
	public void setDay(int day) {
		if(month == 2) {
			if(day < 1 || day > 28) {
				System.out.println("오류입니다");
			} else {
				this.day = day;
			}
		}
	}
}

 

이처럼 클래스 내부에서 사용할 변수나 매서드는 private으로 선언해서 외부에서 접근하지 못하도록 하는 것을 객체 지향에서는 '정보 은닉(information hiding)'이라고 한다. 정보 은닉은 객체 지향 프로그래밍의 특징 중 하나이며 자바에서는 접근 제어자를 사용하여 정보 은닉을 구현한다. 모든 변수를 private으로 선언해야 하는 것은 아니지만, 필요한 경우에는 private으로 선언하여 오류를 막을 수 있다. 

 

자바에서 사용하는 접근 제어자를 정리하면 다음과 같다.

 

접근 제어자 설명
public 외부 클래스 어디에서나 접근할 수 있다.
protected 같은 패키지 내부와 상속 관계의 클래스에서만 접근할 수 있고 그 외 클래스에서는 접근할 수 없다.
아무것도 없는 경우 default이며 같은 패키지 내부에서만 접근할 수 있다.
private 같은 클래스 내부에서만 접근할 수 있다.

 

 

728x90