3장.자바와 객체 지향

자바가 선택한 객체 지향 프로그래밍은 무엇을 뜻하며 어떤 특성이 있고, 그 특성 중 상세 내용을 살펴본다.

클래스와 객체의 관계는 붕어빵틀과 붕어빵이 아니다

예시:

붕어빵틀 붕어빵 = new 붕어빵틀(); // 붕어빵틀 객체가 붕어빵이 될 수 있는가?

금형기계 붕어빵틀 = new 금형기계(); // 금형 기계라는 추상적 객체가 붕어빵 틀이 될 수 있는가?

절대 금형기계와 붕어빵틀이 클래스와 객체 관계가 아니듯 붕어빵틀과 붕어빵도 클래스의 객체 관계가 아니다.

결국 클래스는 분류에 대한 개념이지 실체가 아니다.

  • 사람은 클래스인가? 객체인가?

  • 펭귄은 클래스인가? 객체인가?

위 두 질문은 너무 단순하게도 "클래스"라는 것을 쉽게 알 수 있다. 어떻게 알 수 있었을까?

  • "사람"의 나이는 몇 살일까? 과연 이 질문에 대한 답변을 할 수 있을까? 없다면 클래스이다.

  • "펭귄"의 나이는 몇 살인가? 이 질문 또한 답변을 할 수 있는가? 없다면 당연 클래스이다.

[ 메시지를 따라라 ] 에서 클래스는 이렇게 정의한다.

클래스는 단지 동적인 객체들의 특성과 행위를 정적인 텍스트로 표현하기 위해 사용할 수 있는 추상화 도구일 뿐이다.

클래스는 객체를 표현하기 위한 추상화 도구라고 하였다. 자, 그럼 어떤 내용이 객체일까?

  • 사람(이주환) 의 나이는 몇 살인가?

위 질문은 우리가 쉽게 답변할 수 있다. 그 이유는 객체는 특성과 행위를 실체로 갖고 있기 때문이다.

추상화는 모델링이다

추상화란 구체적인 것을 분해해서 관찰자가 관심 있는 특성만 가지고 재조합하는 것이다.

세상에 존재하는 유일무이한 객체를 특성(속성 + 기능)에 따라 분류해 보니 객첼르 통칭할 수 있는 집합적 개념, 즉 클래스(분류)가 나오게 된다.

  • 객체는 유일무이한 사물이다.

  • 클래스는 같은 특성을 지닌 여러 객체를 총칭하는 집합의 개념이다.

추상화를 누군가에게 설명할 때 해당 개념에 대한 불필요한 정보는 과감히 버리고 관심 있는 내용에 집중해야 한다고 말 하곤 한다.

만약, 파일을 업로드 하는 행위가 있다고 가정해보자. 여기서 추상화해야 할 것은 업로드이다.

우리가 로컬 디스크에 파일을 업로드 하는 행위에 대해 사용자에게 알려줄 필요가 없기 때문에 우리는 이 점을 과감히 버리고, "파일을 업로드" 한다 라는 문장으로 설명한다.

추상화를 하지 않고 설명한다면, "이미지를 Multipart 데이터로 변환하여 파일 크기를 검증하고, 로컬 디스크에 이미지 파일을 쓰고 데이터베이스에 URL 을 저장한다."

파일 업로드가 이렇게 긴 과정을 설명하게 되었다. 우리는 소통할 때 추상적인 말을 자주 사용하는데 그 이유는 상대방이 알고 있는 구체적인 내용은 과감히 버리고 우리가 관심있는 부분에 대해서 집중해야 내용을 이해하는 데 덜 피곤하기 때문이다.

지역 변수는 별도로 초기화 해야하는데, 객체의 멤버 변수는 왜 자동으로 초기화 해줄까?

객체 속성은 힙 영역에 객체가 생성되면 바로 그 때 각 객체안에 멤버 속성을 위한 메모리 공간이 할당된다.

멤버 변수는 "공유 변수"의 성격을 가지고 있기 때문에 자동으로 초기화 하는 반면, 지역 변수는 "한 지역"에서만 쓰는 변수이기 때문에 직접 초기화 해야한다.

변수 자체가 공유 가능성을 보고, 자동으로 초기화 할 것인지 말지를 결정하게된다.

  • 지역 변수 같은 경우 {} 범위에 해당하는 내에서만 사용되기 때문에 직접 초기화 해야하는 것이고, 멤버 변수는 {} 범위 밖에서도 참조가 가능하기 때문이다.

객체지향에서의 상속은 재사용과 확장이다

객체 지향에서의 상속은 상위 클래스의 특성을 하위 클래스에서 상속(특정 상속) 하고 거기에 더해 필요한 특성을 추가, 즉 확장해서 사용할 수 있다.

상위 클래스 쪽으로 갈수록 "추상화" 또는 "일반화" 됐다고 말 하며, 하위 클래스 쪽으로 갈수록 "구체화" 또는 "특수화" 됐다고 말한다.

상속한다는 행위는 상위 클래스의 특성을 상속한다는 의미일 뿐, 부모-자식 관계가 성립되지 않는다. 이 문제는 클래스와 객체 설명과 비슷한 관점에서 is - a 관계에 대한 오해가 있다.

  • 하위 클래스는 하나의 상위 클래스이다.

  • 펭귄 is a 새 -> 펭귄은 새다.

하지만, 새는 날 수 있지만 펭귄은 날 수 없다. 이는 LSP(리스코프 치환 원칙)을 어긋나는데 하위 타입은 부모 타입을 정확히 대체할 수 있어야 한다는 내용이다. 펭귄이 새를 대체하면 날 수 없기 때문에 대체 불가능한 상황이 되기 때문에 이 논법이 오류가 있다.

이보다 더 명확하게 표현하기 위해서 MSDN(마이크로소프트 개발자 사이트) 에서는 is a 관계를 a kind of 로 명시한다.

  • 하위클래스 is a kind of 상위 클래스 -> 펭귄은 새의 한 분류다.

상속의 특성

  • 상속은 상위 클래스의 특성을 재사용하는 것

  • 상속은 상위 클래스의 특성을 확장하는 것

  • 상속은 is a kind of 관계를 만족해야 하는 것

자바는 왜 다중 상속을 지원하지 않을까?

상속 시 상위 클래스의 행위를 만족하는 분류라고 하였다. 이 때, 동물이라는 상위 클래스에 사람 과 강아지를 상속 받았다고 가정해보자.

동물은 걸을 수 있다. 그럼, 사람도 걷고 동물도 걷는데 네 발로 걸어야할까? 두 발로 걸어야할까?

이 같은 문제를 "다중 상속의 다이아몬드 문제"라고 하고, 다중 상속은 득실관계에서 실이 더 많았기에 자바에서는 다중 상속을 포기하는 대신 인터페이스를 도입 하여 다이아몬드 문제를 풀어냈다.

상속 관계에서 메모리 관점

하위 클래스의 인스턴스가 생성 될 때 상위 클래스의 인스턴스도 함께 생성된다. 그리고 생략 되어있지만, 모든 클래스의 최상위 클래스인 Object 클래스의 인스턴스도 함께 생성된다.

Last updated