객체지향 프로그래밍의 가장 큰 특징인 정보 은닉에 대해 알아보도록 하겠습니다.

 

접근제어자(acces modifier)

  •  접근 제어자는 변수, 메서드, 생성자에 대한 접근 권한을 지정하는 역할을 하고 public, private, protected, 생락(기본접근 제어자) 4가지 종류가 있습니다.
  • public은 변수에 대한 모든 접근을 허용하는 것이고 private을 사용하면 클래스 내부에서만 사용되고 외부에서 접근할 수 없습니다. protected는 클래스가 상속될 때 private 변수나 메서드를 public하게 오픈하고 싶을때 사용되는 것인데 상속을 배운 후 더 자세히 알아보도록 하겠습니다. 마지막으로 생략하는 경우는 기본접근 제어자라고 부르며 같은 페키지내에서만 참조할 수 있게 허용하는 기능을 합니다.

정보 은닉(information hiding)

  • 정보 은닉은 private 키워드를 활용해서 외부에서 클래스 내부의 정보에 접근하지 못하도록 하는 기능을 말합니다.
  • private 변수를 외부에서 접근하게 하려면 public 메서드를 사용하여 값을 입력하거나 읽을 수 있습니다. 이는 클래스 내부의 데이터를 잘못 사용하는 오류를 방지하기 위해 사용 됩니다.
package hiding;

public class MyDate {

	int day;
	int month;
	int year;
}
  • 새로운 package hiding을 만든 후 Mydate 클래스를 생성하여 다음과 같이 접근제어자를 생략한 멤버 변수를 선언합니다.
 package hiding;

public class MyDateTest {

	public static void main(String[] args) {

		MyDate date = new MyDate();
		
		date.day = 10;
		date.month = 7;
		date.year = 2020;

	}

}
  • 같은 hiding 페키지 안에 다음과같이 MyDateTest 클래스를 만들고 MyDate 인스턴스를 생성한 후 각각 멤버변수 값을 입력해주면 오류없이 입력되는 것을 확인 할 수 있습니다.  
  • 하지만 MyDateTest를 hiding페키지가 아닌 다른 페키지로 옮기면 오류가 생기는데 hiding 페키지를 벗어났기 때문에 멤버변수에 접근권한이 없어졌기 때문입니다.
public class MyDateTest {

	public static void main(String[] args) {

		MyDate date = new MyDate();
		
		date.day = 100;
		date.month = 70;
		date.year = 20200;

	}

}
  • 만약 사용자가 변수들의 값을 위의 코드 처럼 잘못 입력하게 되면 프로그래머가 의도하지 않은 결과 값이 나올 수 있기 때문에 접근제어자를 통해 정보 은닉하고 public메서드를 사용해 변수에 접근하게 합니다.
package hiding;

public class MyDate {
	//1번
	private int day;
	private int month;
	private int year;
    //2번
	public void setDay(int day) {
		
		this.day = day;
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {

		this.month = month; 
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
	public int getDay() {
		
		return day;
	}
}
  • 정보 은닉을 위해 1번과 같이 멤버 변수들의 접근제어자 private을 입력해 줍니다.
  • 그 후 다른 클래스에서 멤버 변수에 대한 접근 할 수 있게 만들기 위해 2번과 같이 public 메서드인 get~/set~ 메서드를 만들어 줍니다. get 메서드는 변수를 읽어오는 역할을 하고 set 메서드는 변수에 갑을 대입하는 역할을 합니다.
  • set~메서드 안에 this. 은 멤버 변수와 매개 변수와 같을 때 this.뒤의 변수는 멤버 변수임을 알려주는 역할을 합니다. this.에 관한 자세한 내용은 뒤에 더 배우도록 하겠습니다.
  • set과 get은 save/load 등 다른 메서드명으로 쓰는게 가능하지만 Java에서는 일반적으로 set/goal을 많이 씁니다. 또한 하나의 set/goal 메서드를 만들고 오른쪽클릭 - Source - Generate Getters and Setters를 클릭하면 나머지 변수에 대한 set/goal 메서드를 자동 완성합니다.
public class MyDateTest {

	public static void main(String[] args) {

		MyDate date = new MyDate();
		
		date.setYear(2020);
		date.setMonth(7);
		date.setDay(10);
	}

}
  • MyDateTest 클래스에서 앞에서 설정한 set~메서드를 통해 값을 입력 할 수 있습니다. 하지만 아직 여전히 값이 잘못 입력될 수 있다는 위험성이 있습니다.
public class MyDate {

	private int day;
	private int month;
	private int year;
	//1번
	private boolean isValid;
	
	public void setDay(int day) {
		
		this.day = day;
	}
	
	public int getMonth() {
		return month;
	}
    //2번
	public void setMonth(int month) {
		if (month > 12 || month < 1) {
			isValid = false;
		} else {
		this.month = month; }
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public int getDay() {
		
		return day;
	}
	
    //3번
	public void showDate() {
		
		if (isValid) {
			System.out.println(year + "년" + month + "월" + day + "일 입니다.");
		} else {
			System.out.println("유효하지 않은 날짜 입니다.");
		}
	}
}
  • 사용자가 입력하는 값의 범위를 지정하기 위해 2번과 같이 set~메서드 안에 조건문을 통해 특정 범위의 값만 입력되고 그렇지 않을 경우 다른 수행문을 수행 하도록 지정할 수 있습니다.
  • 위의 코드의 경우 1번과 같이 boolean 변수를 지정 후 2번에서 입력 값의 범위를 넘어설 경우 false를 입력하게 되게하여 3번 출력문에서 false일경우 "유효하지 않은 날짜 입니다"라는 메세지를 출력할 수 있게 작성되었습니다. 
  • 참고로 입력값을 받지 않고 클래스에서 입력되어 있는 값을 읽기만 하는 경우라면 set메서드를 작성하지않고 get메서드만 작성하면 됩니다.
  • 정리해 보면 위와 같이 프로그래머가 사용자가 멤버 변수에 대해 조건적인 접근이 필요하다고 판단 하는 경우 변수에 private이라는 접근제어자를 사용하여 정보를 은닉하고 public메서드가 지정한 방식으로만 변수에 접근 할 수 있게 해야 합니다.

+ Recent posts