캡슐화(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를 이용하면 간접 접근가능. } }