정보 은닉 캡슐화

이가현·2023년 8월 6일
0

코틀린

목록 보기
5/12

정보 은닉 캡슐화

클래스를 작성할 때 숨겨야 하는 속성이나 기능이 있을 수 있다. 이러한 개념을 캡슐화라고 한다.

가시성 지시자

각 클래스나 메서드, 프로퍼티의 접근 범위를 가시성이라고 한다. 클래스나 메서드, 프로퍼티에서 가시성 지시자에 의해 공개할 부분과 숨길 부분을 정해줄 수 있다.

private : 이 요소는 외부에서 접근할 수 없다.
public : 이 요소는 어디서든 접근이 가능하다.(기본값)
protected : 외부에서 접근할 수 없으나 하위 상속 요소에서는 가능하다.
internal : 같은 정의의 모듈 내부에서는 접근이 가능하다.

클래스의 주생성자에 가시성 지시자를 사용하려면 constructor 키워드를 생략할 수 없다.

private

접근 범위가 선언된 요소에서 한정하는 가시성 지시자이다. 예를 들어 private와 함께 선언하면 그 클래스 안의 멤버만 접근할 수 있다.


PrivateClass 클래스는 private로 선언되어 있으므로 다른 파일에서 접근할 수 없다. 같은 파일에서는 PrivateClass의 객체를 생성할 수 있다. 만일 다른 클래스에서 프로퍼티로서 PrivateClass의 객체를 지정하려면 똑같이 private로 선언해야 한다. 객체를 생성했다고 하더라도 PrivateClass의 멤버인 i와 privateFunc( ) 메서드가 private으로 선언되었기 때문에 다른 클래스나 main( ) 같은 최상위 함수에서 접근할 수 없다.

protected

protected 지시자는 최상위에 선언된 요소에는 지정할 수 없고 클래스나 인터페이스와 같은 요소의 멤버에만 지정할 수 있다. 멤버가 클래스인 경우에는 protected로 선언할 수 있다.


하위 클래스인 Derived에서 protected클래스의 메서드, 프로퍼티에 접근 가능하다. 다만 외부 클래스나 객체 생성 후 점( . ) 표기를 통해 protected 멤버에 접근하는 것은 허용하지 않는다.

internal

프로젝트 단위의 모듈을 가리키기도 한다. 코틀린에서는 패키지에 제한하지 않고 하나의 모듈 단위를 대변하는 internal을 쓴다. internal의 접근 범위는 프로젝트 전체가 된다.

이제 같은 프로젝트의 모듈에만 있으면 어디서든 접근이 가능하다.


만일 패키지 이름이 다르다면 import 구문을 사용하면 된다.

가시성 지시자와 클래스의 관계

  • - : private
  • + : pulbic
  • # : protected
  • ~ : internal (아직 지정되지 않아 package의 ~을 사용하겠음)

다이아몬드 화살표는 Base 클래스 내부에 Nested 클래스가 구성되어있음을 나타낸다. 흰색 머리 화살표는 상속을 나타내고, 일반 화살표는 클래스를 멤버로 가짐을 나타낸다.

protected, private는 하위, 외부 클래스에서 접근 불가능 한 것 같다.

.
.
.

자동차를 위해 Car 클래스를 선언한다.(3번째 줄) 그 다음 이 클래스를 상속하는 클래스로 Tico 클래스를 만든다.(22번째 줄) 도둑은 외부 클래스인 Burglar로 작성한다.(51째 줄)


1번의 Car 클래스의 주 생성자에는 protected 지시자가 있기 때문에 constructor 키워드를 생략할 수 없으며 Car 클래스를 상속한 클래스만이 Car 클래스의 객체를 생성할 수 있다. Car 클래스를 상속받는 Tico 클래스에서는 access( ) 메서드에서 super를 사용해 상위 클래스에 접근을 시도한다. 이 때 private한 year에는 접근할 수 있다. 그 외의 public, protected, internal 요소는 접근할 수 있다.
Burglar 클래스에서는 steal 메서드만 정의하고 있다. 특히 internal은 파일이 달라져도 같은 모듈에만 있으면 접근이 가능하다.

클래스와 클래스의 관계

연관, 의존, 집합, 구성과 같은 관계가 있다. 연관과 의존 관계는 소유의 개념이 없이 어떤 객체에서 또 다른 객체를 '이용한다'고 말 할 수 있다.
객체가 서로 독립적으로 존재할 수 있으며 서로 참조를 유지하면 연관 관계이다. 참조를 유지하지 않는다면 연관보다 약한 의존 관계가 된다. 포함 관계에 있지만 객체의 생명주기가 서로 유지되는 경우에 집합관계가 되며, 포함 관계의 객체가 사라질 때 같이 사라져 생명주기가 유지되지 않으면 구성 관계이다.

연관 관계

Doctor과 Patient 클래스의 객체는 따로 생성되며 서로 독립적인 생명주기를 가지고 있다. 두 클래스가 서로의 객체를 참조하고 있으므로 양방향 참조를 가진다. 단방향이든 양방향이든 각각의 객체의 생명주기에 영향을 주지 않을 때는 연관 관계라고 한다.

의존 관계


Doctor 클래스를 생성하려고 하는데 먼저 Patient의 객체가 필요하다. Doctor 클래스는 주 생성자에 Patient를 매개변수로 받아야 하므로 Patient 객체가 먼저 생성되어 있어야 한다. 따라서 Doctor 클래스는 Patient 클래스에 의존된다.

집합 관계

집합 관계는 연관 관계와 거의 동일하지만 특정 객체를 소유한다는 개념이 추가된 것이다. 아래 코드에서는 연못이 오리를 소유할 수 있는 것이다.

연못은 개념적으로 여럿의 오리를 소유할 수 있다. 오리 입장에서는 한 번에 한 연못에서만 놀 수 있다. 오리 여럿을 추가하기 위해서는 여러 개의 데이터를 담을 수 있는 배열이나 리스트 구조가 필요하다. 여기서는 MutableList< > 구조를 사용했다. 이는 컬렉션이라 부른다. add 메서드를 활용해 members에 추가했다.

구성 관계


Engine 클래스는 Car 클래스의 생명주기에 의존적이다. car 객체를 생성함과 동시에 Engine 클래스의 객체도 생성된다. 집합 관계와 달리 구성 관계에서는 만일 car 객체가 삭제되면 동시에 engine 객체도 삭제된다.

1개의 댓글

comment-user-thumbnail
2023년 8월 6일

훌륭한 글 감사드립니다.

답글 달기