[Java] 객체지향 특성의 추상화와 상속, 인터페이스 사용이유, 클래스 다중상속 안되는 이유

    함수를 통해서 코드를 논리적인 단위로 나누어 블록화가 가능하여 프로그래밍이 편해지고 더욱 더 파격적으로 객체지향을 위한 클래스가 나왔다. 객체지향은 인간의 인지 및 사고 방식까지 프로그래밍에 접목하는 인간 지향을 실천하고 있다.

    아래는 객체지향의 4대 특성중 추상화와 상속을 정리한 글이다.

    추상화

    추상화는 구체적인 것을 분해해서 관찰자가 관심 영역에 있는 특성만 가지고 재조합 하는것 이다. 이것을 모델링이라고 한다. 모델은 실제 사물을 정확히 복제하는게 아니라 목적에 맞게 관심 있는 특성만을 추출해서 표현하는 것이다. 관심 영역에 있는 특성을 애플리케이션 경계(Application Boundary) 라고 한다. 

    즉 추상화는 애플리케이션 경계 내에서 관심 있는 특성들만 추출한 클래스이다.

     

    사람이란 클래스를 모델링 할 때 애플리케이션 경계가 없으면 모델링 할 때 사람의 모든 특성과 모든 행위를 모델링 해야 하지만 애플리케이션 경계가 있기 때문에 필요한 관심 영역만 추출해서 모델링 할 수 있다.

    추상화란 곧 모델링을 뜻한다. 모델링 하는 것은 정답이 없고 사람마다 다를 수 있어서 가장 어렵고 까다로운 작업 영역이다. 

    요구사항을 받고 개발을 진행 하였을때 모델링을 하고 그 다음 상속 관계를 정의 하는 것이다.

    상속

    상속은 상속이 아닌 재사용과 확장(extend)으로 이해 해야 한다. 객체지향에서의 상속은 상위 클래스의 특성을 하위 클래스에서 상속하고 거기에 더해 필요한 특성을 추가, 확장해서 사용할 수 있다는 의미다. 그래서 부모클래스 - 자식클래스 라는 표현보다는 상위 클래스 - 하위 클래스 또는 슈퍼 클래스 - 서브 클래스라고 표현하는 것이 맞다.

    즉 상속은 조직도가 아니라 분류도를 통해서 돼야 하고 조직도가 있으면 같은 레벨에서 상속이 이루어 져야 한다.

    왼쪽 조직도로 상속이 이루어지는것은 잘못된 예이고, 오른쪽 분류도에 의해서 상속이 이루어 지는 것이 맞다. 만약에 조직도를 통해서 상속이 이루어 져야 한다면 같은 레벨 단에서 상속이 이루어 져야 한다.  ex)아버지 -> 삼촌, 아들 -> 딸 

    아래 상속을 만족하는 표현을 보면 더 이해하기 쉽다.

     

    상속을 만족하는 표현

      - 객체 지향의 상속은 상위 클래스의 특성을 재사용하는 것이다.

      - 객체 지향의 상속은 상위 클래스의 특성을 확장하는 것이다.

      - 객체 지향의 상속은 is a kind of 관계를 만족해야 한다.

     

    상속 잘못된 ex)

      - 할아버지 is a kind of 아버지 -> 아버지는 할아버지의 한 분류다.

      - 아버지 is a kind of 아들 -> 아들은 아버지의 한 분류다.

     

    상속 만족 ex)

      - 고래 is a kind of 동물 -> 고래는 동물의 한 분류다.

      - 펭귄 is a kind of 동물 -> 펭귄은 동물의 한 분류다.

     

    인터페이스의 상속

    상속 관계가 is kind of라면 인터페이스는 is able to 이다.

    ex)

      - Serializable 인터페이스 : 직렬화 할 수 있는

      - Cloneable 인터페이스 : 복제할 수 있는

      - Comparable 인터페이스 : 비교할 수 있는

      - Runnable 인터페이스 : 실행 할 수 있는

     

    인터페이스 사용 이유

    인터페이스는 추상화 레벨이 높다. 추상화 레벨이 높을수록 구현부가 적다는 뜻이고 어떤 행위에 대해서 구현할게 많다는 뜻이다.

    인터페이스는 추상화 레벨이 높고, 클래스는 추상화 레벨이 낮다. 인터페이스와 클래스는 왜 나눠져 있을까 라는걸 생각해 봤을때 추상화 레벨의 단계가 극명하게 나눠져 있어 도메인 관점의 개발이 된다.

    만약 어떤 개발을 진행 하려고 할 때 기능 추가가 필요하면 인터페이스에 기능을 추가하고 인터페이스를 상속받은 클래스에서 구현을 해주면 되고, 기능 수정이 필요하면 클래스에서 구현부만 수정해 주면 된다. 또 기능 삭제가 필요하면 인터페이스에서 기능을 삭제하면 상속받은 클래스에서 모든 구현부를 삭제가 간편해진다.

    이 처럼 기능 추가 변경 삭제가 이루어 질 때 다른 로직을 간섭 할 일이 없어 유지보수가 보다 편해진다. 

     

    클래스와 인터페이스의 다중 상속

    클래스는 다중 상속이 안되지만, 인터페이스는 다중 상속이 가능하다. 

    클래스가 다중 상속이 안되는 이유는 아래 그림 처럼 사람 클래스와, 물고기 클래스 둘다 인어 클래스에게 상속을 했을 때 인어는 사람처럼 헤엄쳐야 하는가 물고기 처럼 헤엄쳐야 하는가를 모른다. 이것을 상속의 다이아몬드 문제 라고 한다.

     

    하지만 인터페이스는 사람과 물고기의 헤엄을 칠수 있다를 상속 받고 나서 인어공주 만의 헤엄을 구현하면 되기 때문에 인터페이스는 다중 상속이 가능하다.

     

    정리 : 클래스 다중 상속이 안되는 이유는 같은 메서드명이 있을때 어떤 메서드를 사용해야 될지 몰라서 다중상속이 안되는것이고 인터페이스 다중상속이 되는 이유는 같은 메서드가 있더라도 구현체는 하나이기 때문에 다중상속이 가능하다.

     

     

    참고 : 스프링 입문을 위한 자바 객체 지향의 원리와 이해 / 김종민 /위키북스

    댓글

    Designed by JB FACTORY