<스프링 입문을 위한 자바 객체 지향의 원리와 이해, 김종민 지음 / 위키북스> 를 읽고 정리한 내용입니다.

객체 지향을 이해하기 위한 전제는 아래와 같다.

  • 세상에 존재하는 모든 것은 사물, 즉 객체(object)이다.
  • 각각의 사물은 고유하다.
  • 사물은 속성을 갖는다.
  • 사물은 행위를 한다.

그리고 우리는 각각의 사물을 분류(class)해서 인지한다.
분류 안의 객체들은 속성(property)와 행위(method)를 가진다.

클래스와 객체는 어떻게 구분할까?

클래스는 분류에 대한 개념이지 실체가 아니다. 하지만, 객체는 실체다.

예를 들어, 사람을 클래스로 본다면 객체는 나, 메시, 베르바토프 등등이 되겠다.

객체지향의 4대 특성

  1. 추상화: 모델링
    추상화과 모델링이라는 관점을 살펴보기 전에 간단히 용어를 정리해보겠다.
  • 추상: 사물이나 표상(表象)을 어떤 성질·공통성·본질에 착안하여 그것을 추출(抽出)하여 파악하는 것.
  • 객체(Object): 세상에 존재하는 유일무이한 사물, 클래스의 인스턴스
  • 클래스(Class): 분류, 집합. 같은 속성과 기능을 가진 객체를 총칭하는 개념
  • 인스턴스(Instance): 클래스를 이용해 Object를 만들었다는 것을 강조할때 사용하는 표현
사람 메시 = new 사람();
사람 베르바토프 = new 사람();

클래스를 이용해 유일무이하고 새로운 하나의 사람(객체)을 만들어 객체 참조 변수를 생성했다.

  • 컨텍스트(Context): 애플리케이션 경계 내가 창조하려는 세상은 어떤 세상인가? 내가 만들고자 하는 애플리케이션은 어디에서 사용될 것인가?

지금까지 정의한 용어들을 바탕으로 추상화를 다시 정의해보자면 아래와 같다. 추상화란 구체적인 것을 분해해서 관심 영역(애플리케이션의 경계)에 있는 특성만 가지고 재조합하는 것 = 모델링

애플리케이션 경계 병원 애플리케이션 은행 애플리케이션
사람이란 사람은 환자다. 사람은 고객이다.
클래스 모델링 image image

모델은 실제 사물을 정확히 복제하는 것이 아니라 목적에 따라서 관심 있는 특성만을 추출해서 표현한다.
추상화를 통해 실제 사물을 단순하게 묘사하여 모델을 만들어낸다.

따라서, 모델링을 위해 가장 중요한 것을 추상화이다. 애플리케이션 경계 내에서 관심 있는 특성들만 추출할 수 있어야 한다.

상속: 재사용 + 확장

  • 상속 개념에 대한 오해: 부모나 자식의 관계처럼 계층이나 조직에 관한 개념이 아니다. 확장이나 구체화를 하는 분류와 관련이 깊다.
    이에 따라 로버트 C. 마틴이 주장하는 하위 클래스는 상위 클래스다.를 이해할 수 있다.

    • 포유류는 동물이다.
    • 고래는 포유류이다.
    • 고래는 동물이다.

반면에 조직이나, 계층 구조의 개념으로 상속을 이해하면 아래와 같이 이상한 문장이 생성된다.

  • 아버지는 할아버지다 (?)
  • 아들은 아버지다 (?)
  • 딸은 아버지다 (?)

따라서, 이름을 지을때 클래스명은 분류스럽게, 객체 참조 변수명은 유일무이한 사물처럼 작명해야 한다.

객체 지향에서 상속을 활용하는 방안은 아래와 같다.

  • 객체 지향의 상속은 상위 클래스의 특성을 재사용하는 것이다.
  • 객체 지향의 상속은 상위 클래스의 특성을 확장하는 것이다.
  • 객체 지향의 상속은 is a kind of 관계를 만족해야 한다.

다형성: 사용 편의성

객체 지향에서 다형성은 오버라이딩(overriding)과 오버로딩(overloading)을 말한다.

  • 오버라이딩(overriding): 같은 메서드 이름, 같은 인자 목록으로 상위 클래스의 메서드를 재정의
  • 오버로딩(overloading): 같은 메서드 이름, 다른 인자 목록으로 다수의 메서드를 중복 정의

  • Animal
    public class Animal {
      public String name;
    
      public void showName() {
          System.out.printf("안녕 나는 %s야. 반가워\n", name);
      }
    }
    
  • Penguin
    public class Penguin extends Animal {
      public String habitat;
    
      public void showHabitat() {
          System.out.printf("%s는 %s에 살아\n", name, habitat);
      }
    
      //오버라이딩 - 재정의: 상위클래스의 메서드와 같은 메서드 이름, 같은 인자 리스트
      public void showName() {
          System.out.println("어머 내 이름은 알아서 뭐하게요?");
      }
    
      // 오버로딩 - 중복정의: 같은 메서드 이름, 다른 인자 리스트
      public void showName(String yourName) {
          System.out.printf("%s 안녕, 나는 %s라고 해\n", yourName, name);
      }
    }
    

만약 오버라이딩과 오버로딩이 지원되지 않는다면 같은 이름의 함수를 추가로 만들 수 없다.
이미 사용한 함수명이 아닌 다른 이름과 인자 목록의 함수를 새로 만들어야 한다.
이러한 이유로 오버라이딩과 오버로딩(다형성)에 대해 편의성이라 정의할 수 있겠다.

캡슐화: 정보 은닉

  • 상속을 받지 않았다면 객체 멤버는 객체를 생성한 후 객체 참조 변수를 이용해 접근해야 한다.
  • 정적 멤버는 클래스명.정적멤버 형식으로 접근하는 것을 권장한다. (일관된 형식으로 접근하기 위해서다.)

댓글남기기