서브클래스, 서브타입, 클래스들간의 각종 관계 등에 대해 정리해보고자 시리즈물로 준비했다.

나는 이 부분에 대해 전혀 모르기 때문에 간단한 정리가 될 것이다. 

1. 타입과 클래스들의 관계 그리고 리스코프 치환원칙

2.  Aggregation 과 Composition 개념

3. Subtype 과 Subclass


봐도 봐도 헷갈린다. 그래도 이제는 헷갈릴 때 마다 여러번 봐 놓았었더니 wiki 내용이 조금 와 닿기 시작했다.

wiki 에 있는 Is-a 와 관련된 설명들을 바탕으로 s-a , has-a 등 각종 타입간의 관계와 이를 리스코프 치환 원칙과 연관 지어 정리 해 보기로 했다.

 

 

타입 및 클래스들 사이에 존재하는 각 종 관계들과 리스코프 치환 원칙

리스코프 치환원칙 과 “Java 에서의 is-a 관계” 라는 말로 특정지어서 깔끔하게 정리하고 끝내 야겠다.

  • 타입 및 클래스들 사이에 존재하는 has-a 관계와 is-a 관계 그리고 instance-of 관계
    • super타입/클래스 - sub타입/클래스 관계
      • sub타입/클래스는 super타입/클래스 에 대하여 “type-of(is-a)” 관계를 갖는다.
    • 전체(whole)/엔티티/컨테이너 - 부분(part)/구성요소/멤버 관계
      • aggregation (소유 관계 없음) 관계 : “전체” 는 “부분” 과 “has-a” 관계를 갖는다.
      • composition ( 소유 관계가 존재 ) 관계 : “constituent(구성요소)” 는 “entity” 와 “part-of” 관계를 갖는다.
      • containment 관계 : “member” 는 “container” 에 대해 “member-of” 관계를 갖는다.
    • concept-object(type-token) 관계 : classes(types) 와 instances(objects) 사이의 관계
      • object 는 클래스(타입) 에 대해 instance-of 관계를 갖는다

다양한 관계들에 대한 정의들이다.

나는 여기서 "서브타입" 과 "서브클래스" 가 같은 의미인가? 하는 의문이 생겼다. 이에 대해서는 다음 포스트에서 다룰 예정이다. 굉장히 학문적인 내용이었다.. 

 

또한 여기서 aggregation 과 composition 이라는 것이 등장한다. 둘다 뭔가 집합-부분 사이의 관계를 의미하는 듯 하다.

하지만 "소유관계가 있고 없고" 에서의 차이가 보이는데 이것만 보고는 잘 와닿지 않는다. 

다음 포스트 

에서는 이에 대해 간략하게 정리하며 예시를 들었다.

 

리스코프 치환원칙

다음으로는 리스코프 치환원칙에 대해 살펴보자.

  • 리스코프 치환원칙 : Base 클래스(B) 와 Child 클래스(C) 사이 에 상속 관계가 존재할 경우, B 타입의 어떠한 객체던 간에 C 타입의 객체로 대체 될 수 있다.
    • 중요한 것은 C 타입 객체로 대체 되었을 때 이상 없어야 한다는 것.
    • B 에 대해 기대되는 것이 C 를 통해서도 이뤄져야 한다.
    • LSP 은 내가 체크해 봐야할 세부적인 규칙을 주는 것 으로 볼 수 있다.
    • 따라서 오버라이딩 에서 리턴 타입, 인자 타입 등을 맘대로 변경할 수 없고, 접근 제한 정도를 더 좁게 만들 수도 없다. 그리고 개발자 스스로는 로직이 상위클래스에서 제공되는 것과 완전히 별개의 로직을 작성 하지는 않도록 해야 할 것이다.

 

 

 

나의 결론

“is-a 관계와 리스코프치환원칙이 어떤 차이가 있지? “ 라는 혼란으로부터 각종 관계에 대한 개념을 정리해 보았는데 내 결론은 다음과 같다.

  • is-a 관계 더라도 리스코프 치환원칙을 만족 하느냐 는 개발자가 코드를 어떻게 작성해 놓았느냐 에 따라 달라질 것이다.
    • 언어차원에서 is-a 관계를 가진 클래스들 사이에 "subtyping 과 관련된 강제적인 규칙" 을 지원하지 않는한 , 개발자의 코드에 달려 있는 것 같다.  
    • Java 에서 extends 를 통한 상속을 했다면 이는 is-a 관계를 정의한 것이다. 하지만 서브 클래스에서 로직 구현을 이상하게 짜 놓는다면 B 타입 자리에 C 타입 객체로 대체 할 경우, 어디선가 로직이 깨져버릴 수 있기 때문이다. 이는 Java 에서는 extends 를 통해서 서브타이핑이 가능하긴 하지만, supertype 의 behavior 에 대한 보장은 없기 때문이다. 이와 관련해서는 다음 포스팅에서 이어 서보겠다
  • 리스코프 치환원칙은 다음 포스트에서 이어질 "subtyping" 에 초점을 둔 원칙으로 보인다. 

참조

https://en.wikipedia.org/wiki/Is-a

 

Is-a - Wikipedia

From Wikipedia, the free encyclopedia Subsumption relationship between abstractions In knowledge representation and ontology components, including for object-oriented programming and design (see object-oriented program architecture), is-a (is_a or is a) is

en.wikipedia.org

 

복사했습니다!