본문 바로가기

Programming/JAVA

자바와 객체지향 4대 특성 ( 캡슐화, 상속, 추상화, 다형성 )


 

객체 지향은 인간 지향이다.

 

기존 구조적 프로그래밍 언어는 복잡한 문제도 작은 문제로 분할해 하나씩 정복해 가다보면 해결된다는 전략이다. 즉, 구조적 프로그래밍의 "함수"는 코드를 논리적 단위로 구분하고 분할해 정복하는 것이다.

 

객체 지향의 출발은 '우리가 주변에서 사물을 인지하는 방식대로 프로그래밍'하는 것이다. 0과 1로 대변되는 기계에 맞춰 사고하던 방식을 버리고 현실세계를 인지하는 방식으로 프로그램을 만들기에, 객체 지향은 직관적이다.

 

객체 지향의 큰 그림은 아래와 같다.

 

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

사물을 하나하나 이해하기보다 사물을 분류(class)해서 이해하는 것이 인간의 인지법이다.

 

  • 직립보행을 하며 말을 하는 존재는 사람이라 분류한다.
  • 연미복, 짧은 다리, 날지 못하는 새는 펭귄이라 분류한다.

유재석(object), 박명수(object)와 같은 존재는 사람이라는 분류에 속한다. 그리고 사람이라는 분류 안의 객체(object)들은 나이, 몸무게, 키 등 속성(property)와 먹다, 자다, 울다 등의 행위(method)를 가지고 있다.

 

객체 지향은 인간의 인지, 사고를 프로그래밍에 접목하는 인간(개발자) 지향을 실천하고 있다. 고로 객체 지향은 직관적이다. 

 


클래스 VS 객체

 

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

즉, 사람은 클래스이며 유재석은 실체이기에 객체이다.

 

사람 유재석 = new 사람( );

 


 

 

객체 지향의 4대 특성

 

캡슐화 ( Encapsulation ) : 정보 은닉 ( Information hiding )

 

정보은닉은 접근지정자가 떠오를 것이다. 이를 객체 멤버(인스턴스 멤버)와 정적 멤버(클래스 멤버)가 함께 쓰일 때를 비교하겠다.

 

* 객체 멤버의 접근 제어자

다른 객체의 멤버에 접근하고자 할 때는 해당 객체를 생성한 뒤 접근해야 한다. 즉 정리하자면

 

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

* 참조 변수의 복사

값에 의한 복사(Call by value)는 값이 복사되며, 두 변수는 서로에게 영향을 주지 않는다. 반면에 참조 변수의 복사는 Call by reference로 두 변수의 변화는 같은 주소를 참조하기에 서로에게 영향을 준다.

 

  • 기본 자료형 변수는 값을 값 자체로 판단한다.
  • 참조 자료형 변수는 값을 주소, 즉 포인터로 판단한다.
  • 기본 자료형 변수를 복사할 때, 참조 자료형 변수를 복사할 때 일어나는 일은 같다. ( 가진 값을 복사해서 넘겨준다는 점에서 말이다. )

 

상속 ( Inheritance ) : 재사용

 

사속은 재사용과 확장으로 이해하는 것이 바람직하다. 객체 지향에서의 상속은 상위 클래스 특성을 하위 클래스에서 상속하고, 필요한 특성을 추가하여 확장해 사용할 수 있다는 의미이다.

 

분류도를 기억하면 좀 더 좋은데, 상위 클래스 쪽으로 갈수록 추상화, 일반화되었다고 말하며, 하위 클래스로 갈수록 구체화, 특수화되었다고 이야기한다.

 

상속을 함으로 상위 클래스에 있는 메서드와 변수를 그대로 사용할 수 있다. 즉, 재사용이 가능하다.

 

상속의 관계는 ' A is a B '를 만족해야 한다는 이야기가 많지만, 이는 ' A는 B이다.'라는 뜻으로 적절하다고 이야기하긴 애매하다. 그래서 조금 더 정확하게 이야기 하기 위해서는 ' A is a kind of B '관계가 정확하지 않을까 싶다.

즉, ' 하위 클래스 is a kind of 상위 클래스 '로 하여, [ 하위 클래스는 상위 클래스의 한 종류이다. ] 이렇게 말이다.

 

잠깐 정리하고 넘어가자면

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

또한 자바는 다중상속을 지원하지 않는다. 

그렇다면 인터페이스를 살펴보자. 자바는 다중 상속을 포기하고 인터페이스를 도입하고 있다. 상속과 달리 인터페이스는 [ 구현 클래스 is able to 인터페이스 ] 관계일때 적절하다고 볼 수 있다.

 

즉, 구현하고자 하는 클래스가 인터페이스를 할 수 있다. 이로 인터페이스를 상속 받는 클래스의 구현을 강제할 수 있다.

그렇다면 바람직한 상위 클래스와 인터페이스는 무엇일까?

 

  • 상위 클래스는 물려줄 특성이 풍부할수록 좋고 [ LSP ( 리스코프 치환 원칙 )에 따른 이유 ]
  • 인터페이스는 구현을 강제할 메서드의 개수가 적을수록 좋다. [ ISP ( 인터페이스 분할 원칙 )에 따른 이유 ]

 

추상화 ( Abastraction ) : 모델링

 

추상의 사전적 의미는 여러 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출해 파악하는 작용이다.

 

객체 지향의 추상화는 곧 모델링이라고 볼 수 있다. 추상화는 구체적인 것을 분해해 관찰자가 관심 있는 특성만으로 재조합하는 것이라 정리할 수 있다.

 

객체 지향의 4대 특성은 클래스를 통해 구현된다.

객체는 세상에 존재하는 유일무이한 사물이다. 이러한 객체를 특성(속성 + 기능)으로 분류하면 클래스가 나오게 된다.

 

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

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

 

클래스로 객체를 생성할 수 있는데, 이때 객체를 만들었다는 것을 강조하기 위해 'instance'라는 표현을 사용한다.

 

  • 객체(Object) = 클래스 인스턴스

추상화를 한 번 더 정리하자면, 추상화는 구체적인 것을 분해해 관심 영역에 대한 특성만으로 재조합하는 것이다. 즉, 구체적인 것을 분해해 관심영역( Application Boundary )에 있는 특성만으로 제조합하는 것(모델링)이다.

 

이러한 모델링은 실제 사물을 정확히 복제하는 것이 아닌, 목적에 맞게 관심 있는 특성만 추출해 표현하는 것이다. 즉, 모델링을 통해 실제 사물을 단순하게 묘사하는 것이다.

 

중요한 부분을 정리해보겠다.

 

  • OOP의 추상화는 모델링이다.
  • 클래스 : 객체 = 사람 : 유재석
  • 클래스 설계에서는 추상화가 사용된다.
  • 클래스 설계를 위해서는 어플리케이션 경계부터 정해야 한다.
  • 객체 지향에서 추상화의 결과는 클래스이다.


  • 상속을 통한 추상화, 구체화
  • 인터페이스를 통한 추상화
  • 다형성을 통한 추상화

위에서 보았듯이 자바에서의 추상화는 class를 통해 지원하고 있다. [ 추상화 = 모델링 = 자바 class 키워드 ]

 

  • 클래스 객체_참조_변수 = new 클래스( );

객체 참조 변수는 클래스의 인스턴스를 참조한다.

 

 

클래스 멤버 vs 객체 멤버 = static 멤버 vs 인스턴스 멤버

 

static 키워드가 붙은 속성은 클래스 멤버 속성이며, static이 안 붙은 속성은 객체 멤버 속서잉라고 한다. 클래스 멤버들은 static 키워드와 함께 사용되며, T 메모리 상에서 static 영역에 상주해 static(정적) 멤버라고도 한다.

 

정리하자면, [ 클래스 멤버 = static 멤버 = 정적 멤버 ], [ 객체 멤버 = 인스턴스 멤버 ] 이다. 이는 JVM 구동시 T 메모리 static 영역에 바로 배치되어 객체 존재 여부와 관계 없이 사용할 수 있다.

 

 

다형성 ( Polymorphism ) : 사용 편의

 

다형성이라 하면 대표적으로 오버로딩(overloading)과 오버라이딩(overriding)이 존재한다.

 

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

상위 클래스 타입의 객체 참조 변수를 사용하여도, 하위 클래스에서 오버라이딩(재정의)한 메서드가 호출된다. 이로 형변환을 신경쓰지 않아도 되어, 깔끔한 코드 유지가 가능하다.

 

이로 개발자는 다형성을 통해 프로그램을 작성할 때 사용편의성을 가질 수 있다.

 

'Programming > JAVA' 카테고리의 다른 글

자바, final 키워드  (0) 2021.04.04
자바의 static 블록  (0) 2021.03.31
자바의 생성자(Constructor) : new  (0) 2021.03.31
추상 메서드와 추상 클래스 ( abstract )  (0) 2021.03.31
객체 지향 설계 5원칙, SOLID 원칙  (0) 2021.03.23