캡슐화(Encapsulation)란?
"public interface, private implementation"
Interface는 공개하고 implementation 구현부는 비공개한다.
캡슐화의 장점은
1. 구현부를 비공개함으로써 정보를 보고하고 은닉할 수 있다.
2. 인터페이스 부분을 그대로 두고 구현부만 바꿀 수 있다. (낮은 결합도로 유지보수 향상)
3. 사용하는 측은 구현부를 몰라고 인터페이스만 가지고 사용할 수 있다.(생상성 향상)
이러한 캡슐화는 접근제어자를 이용하여 구현할 수 있다.
접근제어자 |
접근 범위 |
public |
어느 곳에서든 접근이 가능 |
protected |
같은 팩키지 내에서만 접근 가능하며, 상속관계시 다른 팩키지에서도 사용이 가능하다 |
[default] |
같은 팩키지 내에서만 접근 가능 |
private |
자신의 클래스 내에서만 접근이 가능 |
1) public
public으로 변수 선언
package tistory.encap;
public class AccessTest {
public String name="public 접근제어자";
//접근제어자는 : public, 데이터 타입: String, 변수명:name
}
다른 팩키지에서 객체화 후 실행
package tistory.encap.test;
import tistory.encap.AccessTest;
public class Test {
public static void main(String[] args) {
AccessTest at=new AccessTest(); //AccessTest 클래스 객체 생성
System.out.println(at.name); //콘솔창에 name 값 출력
//결과 값: public 접근제어자
//다른 팩키지에서 클래스 접근 가능
}
}
2) protected
protected 로 변수 선언
package tistory.encap;
public class AccessTest {
protected String name="protected 접근제어자";
//접근제어자는 : protected, 데이터 타입: String, 변수명:name
}
다른 팩키지에서 객체화 후 실행 (에러)
package tistory.encap.test;
import tistory.encap.AccessTest;
public class Test {
public static void main(String[] args) {
AccessTest at=new AccessTest(); //AccessTest 클래스 객체 생성
System.out.println(at.name); //콘솔창에 name 값 출력
//에러메세지: The field AccessTest.name is not visible
//다른 팩키지에서 클래스 접근 불가
}
}
상속 관계로 변경 후 테스트
package tistory.encap;
public class AccessTest {
protected String name="protected 접근제어자";
//접근제어자는 : protected, 데이터 타입: String, 변수명:name
}
package tistory.encap.test;
import tistory.encap.AccessTest;
public class Test extends AccessTest{ //AccessTest를 상속 받는다.
public static void main(String[] args) {
Test at=new Test(); //AccessTest를 상속받은 Test 클래스 객체 생성
System.out.println(at.name); //콘솔창에 name 값 출력
//결과값: protected 접근제어자
//protected 접근제어자는 상속 관계일 때, 팩키지가 달라도 접근이 가능하다
}
}
3) [default]
default로 변경 후 테스트
package tistory.encap;
public class AccessTest {
String name="[default] 접근제어자";
//접근제어자는 : [default], 데이터 타입: String, 변수명:name
}
에러가 난다
package tistory.encap.test;
import tistory.encap.AccessTest;
public class Test extends AccessTest{ //AccessTest를 상속 받는다.
public static void main(String[] args) {
Test at=new Test(); //AccessTest를 상속받은 Test 클래스 객체 생성
System.out.println(at.name); //상속관계라도 에러가 난다
//에러메세지: The field AccessTest.name is not visible
//default 접근제어자는 상속 관계라도 팩키지가 다르면 접근이 불가능하다
}
}
같은 팩키지로 이동 후 테스트
package tistory.encap; //팩키지 이동
import tistory.encap.AccessTest;
public class Test extends AccessTest{ //AccessTest를 상속 받는다.
public static void main(String[] args) {
Test at=new Test(); //AccessTest를 상속받은 Test 클래스 객체 생성
System.out.println(at.name); //같은 팩키지로 이동시에는 에러가 안난다.
//결과값: [default] 접근제어자
//default 접근제어자는 상속 관계라도 팩키지가 다르면 접근이 불가능하다
//같은 팩키지 내에서는 접근가능
}
}
4) private
private 변경 후 같은 팩키지 내에서 테스트
package tistory.encap;
public class AccessTest {
private String name="private 접근제어자";
//접근제어자는 : private, 데이터 타입: String, 변수명:name
}
에러가 난다
package tistory.encap; //팩키지 이동
import tistory.encap.AccessTest;
public class Test extends AccessTest{ //AccessTest를 상속 받는다.
public static void main(String[] args) {
Test at=new Test(); //AccessTest를 상속받은 Test 클래스 객체 생성
System.out.println(at.name); //같은 팩키지라도 에러가 난다
//에러메세지: The field AccessTest.name is not visible
//private 접근제어가는 같은 팩키지라도 에러가 난다.
}
}
private 접근 제어자 다른 클래스 또는 팩키지에서는
접근 불가 ,
즉 같은 클래스내에서만 접근 가능
package tistory.encap;
public class AccessTest {
private String name="private 접근제어자";
//접근제어자는 : private, 데이터 타입: String, 변수명:name
// private 접근 제어자 -> 다른 클래스 또는 팩키지에서는
// 접근 불가 , 즉 같은 클래스내에서만 접근 가능
// getter 를 이용해 간접 접근은 허용
// getter : 사용자가 필요한 정보를 반환하는 메서드
public String getName() {
return name;
}
}
그러나 간접 접근이 가능하다
package tistory.encap;
public class Test {
public static void main(String[] args) {
AccessTest at=new AccessTest(); //AccessTest를 상속받은 Test 클래스 객체 생성
System.out.println(at.getName()); //getter를 이용해 접근해본다
//실행 결과: private 접근제어자
//private 접근제어자는 같은 클래스 내에서만 접근가능하지만
// getter를 이용하면 간접 접근가능.
}
}