1. 접근 제어 지시자 (access modifier)
- 클래스 외부에서 클래스의 멤버 변수, 메서드, 생성자를 사용할 수 있는지 여부를 지정하는 키워드
- private : 같은 클래스 내부에서만 접근 가능 (외부 클래스, 상속 관계의 클래스에서도 접근 불가)
- 아무것도 없음 (default) : 같은 패키지 내부에서만 접근 가능 (상속 관계라도 패키지가 다르면 접근 불가)
- protected : 같은 패키지나 상속관계의 클래스에서 접근 가능하고 그 외 외부에서는 접근할 수 없음
- public : 클래스의 외부 어디서나 접근 할 수 있음
2. get()/ set() 메서드
- private 으로 선언된 멤버 변수(필드) 에 대한 접근, 수정할 수 있는 메서드를 public으로 제공
- get() 메서드만 제공되는 경우는 read-only 필드가 된다.
- 이클립스에서 자동으로 생성됨
ex) eclipse class화면 > 우클릭 > Source > Generate Getter and Setter
* 왜 굳이 class 멤버 변수를 public으로 하지 않고 private으로 접근 제어를 하는지?
-> 만약 public이나 default로 설정해서 다른 클래스 객체에서 직접 변수에 접근을 하게 되면 해당 변수를 오용해서 사용할 수 있다. 예를 들어, int month라는 변수에 접근하여 설정할 때 month는 1~12까지만 유효한 value이다.
그러나 객체에서 직접 값을 설정한다면 integer 범위 내에서 어떠한 수라도 넣을 수 있다.
그러나 setter(메서드)를 이용한다면 메서드에서 예외처리를 진행하여 변수 사용의 오용을 예방할 수있다.
setter 메서드에 1~12 사이의 값만 month에 들어가게끔 설정하고 그 이외의 값은 예외처리를 하면 구현 가능
3. 정보 은닉
- private으로 제어한 멤버 변수도 public 메서드가 제공되면 접근 가능하지만 변수가 public으로 공개되었을 때보다
pirvate일 때 각 변수에 대한 제한을 public 메서드에서 제어할 수 있다.
- 객체 지향 프로그램에서 정보 은닉은 필요한 외부에서 접근 가능한 최소한의 정보를 오픈함으로써 객체의 오류를 방지하여 클라이언트 객체가 더 효율적으로 객체를 활용할 수 있도록 해준다.
- BirthDay.java
package ch10; public class BirthDay { private int day; private int month; private int year; private boolean isValid; public int getDay() { return day; } public void setDay(int day) { this.day = day; } public int getMonth() { return month; } public void setMonth(int month) { if( month <1 || month >12) { isValid = false; }else { isValid = true; this.month = month; } } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public void showDate() { if(isValid) { System.out.println(year + "년 " + month + "월 " + day + "일 입니다."); } else { System.out.println("유효하지 않은 날짜 입니다."); } } } |
> setMonth 메서드에서 isValid라는 boolean 타입을 통해 객체 사용의 오류를 방지하도록 예외처리를 한다.
- BirthDayTest.java
package ch10; public class BirthDayTest { public static void main(String[] args) { BirthDay date = new BirthDay(); date.setYear(2021); date.setMonth(12); date.setDay(20); date.showDate(); } } |
4. 캡슐화
4-1. 정보 은닉을 활용한 캡슐화
- 꼭 필요한 정보와 기능만 외부에 오픈 함.
- 대부분의 멤버 변수와 메서드를 감추고 외부에 통합된 인터페이스만은 제공하여 일관된 기능을 구현 하게 한다.
- 각각의 메서드나 멤버 변수를 접근함으로써 발생하는 오류를 최소화 한다.
4-2. 레포트 예제
- MakeReport.java
package ch11; public class MakeReport { StringBuffer buffer = new StringBuffer(); private String line = "======================================\n"; private String title = " 이름\t 주소\t\t 전화번호 \n"; private void makeHeader() { buffer.append(line); buffer.append(title); buffer.append(line); } private void makeBody() { buffer.append("James \t"); buffer.append("Seoul Korea \t"); buffer.append("010-2222-xxxx\n"); buffer.append("Tomas \t"); buffer.append("NewYork US \t"); buffer.append("010-7777-xxxx\n"); } private void makeFooter() { buffer.append(line); } public String getReport() { makeHeader(); makeBody(); makeFooter(); return buffer.toString(); } } |
> makeHeader(), makeBody(), makeFooter()를 클라이언트에게 오픈해봤자 큰 의미도 없을 뿐더러, 오픈하게되면 클라이언트는 해당 메서드를 순서대로 써야하는 방법도 알고 있어야 한다. (사실 클라이언트가 그걸 알 필요가 없다.)
그냥 단순히 getReport()만 호출하면 레포트를 응답받게 하는 것이 깔끔하다. 이것이 캡슐화의 정석이다.
- MakeReportTest.java
package ch11; public class MakeReportTest { public static void main(String[] args) { MakeReport report = new MakeReport(); String builder = report.getReport(); // Client 코드에서 볼 수 있는 메서드는 getReport 뿐이다. // Client 에서는 정해진 메서드 호출만 가능하고 해당 기능만 사용 할 수있다. System.out.println(builder); } } |
'개발공부 > Java' 카테고리의 다른 글
[Java] 08. 객체협력 프로그래밍 예제 (0) | 2021.11.24 |
---|---|
[Java] 07. 객체 자신을 가리키는 this / 객체 간의 Collaboration (0) | 2021.11.22 |
[Java] 05. 참조 자료형 변수 (0) | 2021.11.18 |
[Java] 04. 생성자란? (Constructor) (0) | 2021.11.17 |
[Java] 03. 인스턴스 생성과 힙 메모리 (heap memory) (0) | 2021.11.17 |