Java 객체지향 프로그래밍(OOP)
객체지향(object oriented)와 절차지향(procedural oriented)
프로그래밍의 초기 방식은 절차지향이었다. 말 그대로 처음부터 코드가 기술된대로 차례대로 실행이 되는 방식으로 컴퓨터의 처리 구조와 비슷해 실행 속도가 빠르다. 하지만 프로그램이 더 커지고 복잡하게 되면 유지 보수가 어려워지고, 정해진 순서대로 입력을 해야 하므로 순서가 바뀌면 결과값을 도출하기 어렵다. 그래서 대형 프로젝트에 적합하지 않다.
객체 지향 프로그래밍은 객체라는 논리적인 단위로 실행되는 방식으로 데이터의 처리방법보다는 프로그램이 사용하고 있는 데이터를 중요하게 생각한다. 처리속도는 상대적으로 느리고 설계에 많은 시간이 투자되기도 하지만, 코드의 재활용성이 높고 유지보수가 쉽다. 분석 설계의 전환이쉽기도 하여 대형 프로젝트에 적합하다.
객체지향 프로그래밍은 대표적인 언어로는 자바, C#, Object-C 등이 있고, 절차지향언어로는 C, Pascal, Fortran 등이 있다.
객체 (object)
객체란 정보를 효율적으로 관리하기 위한 논리적인 단위이라고 할 수 있다. 객체는 속성(attribute) 또는 필드(field)라고 부르는 변수와 정보를 처리하는 절차를 기술하고 있는 메소드(method)로 이루워져 있다.
현실 세계에서 우리가 흔하게 보는 모든 사물 및 생물, 유무형의 존재 등에 비유되며 객체로 표현이 가능하다. 예를 들면, 사람은 이름, 키, 몸무게, 혈액형 등의 특징을 가지고 있고 식사, 일, 공부 등의 행위을 한다. 여기서 특징과 행위를 프로그래밍적으로 표현하면 속성과 메소드가 된다.
클래스(class)
프로그래밍을 작성하다 보면 같은 형태의 객체를 생성해야 하는 경우가 있다. 예를 들면, 회사에서 인사 시스템을 만든다고 하자. 이때 여러 사원들의 속성이 같은 형태의 데이터들로 존재하고 이들은 같은 형태의 일을 하게 될 것이다. 여러 사원들에 대한 객체를 생성하기 위해 프로그래밍을 해야 한다면, 사원의 인사 변동이 생길 때마다 프로그램이 변경되는 사태가 벌어질지도 모른다.
그래서 객체지향에서는 같은 객체를 만들기 위해 형틀(template) 즉, 클래스를 이용한다. 객체는 클래스를 바탕으로 생성이 되고 같은 클래스로 생성된 객체는 모두 같은 속성과 메소드를 가지게 된다.
인사 시스템으로 따지면 각 사원마다 실제 이름과 경력들의 속성에 각각 다른 값이 들어가 있어서 이름으로 검색하거나 하는 일이 조금씩 난위도 및 역활이 다른 일을 할수 있게 업무 배치를 할 수 있게 된다.
보통 프로그래밍을 건물에 비교하는 경우가 많다. 여기서도 건축에 비교해서 설명을 하자면, 클래스(Class)는 건물 설계도 이고, 건축 설계도에 의해 만들어진 건물을 객체(Object)라고 볼수 있다.
상속 (inheritance)
상속은 상위에서 가지고 있는 것을 하위에게 물려주거나, 하위에서 물려받는 것이다. 객체 지향 프로그래밍에서도 동일하게 상위 객체가 가지고 있는 속성과 메소드를 하위 객체에서 물려주거나 물려바는 것이다.
상속을 받으므로써 코드의 재사용이 가능해지고 코드의 중복을 줄여준다. 이렇게 되므로써 유지 보수의 편의성도 제공한다.
캡슐화(encapsulation)
객체는 여러 속성과 여러 기능을 가지고 있다. 객체를 사용하는 입장에서는 하나의 기능이 내부에서 실제 어떻게 처리가 되는지 구지 알 필요도 없고 어떻게 처리가 되는지 몰라도 객체 사용하는데 아무런 지장이 없다. 단지, 어떤 값을 입력해서 어떤 출력 값이 나오는지만 알면 된다. 이런 개념이 캡슐화이다.
더 쉽게 설명을 하자면 자동차를 운전하는 사람이 자동차의 엔진구동이나 바퀴가 돌아가는 원리 등과 같은 모든 동작 방법을 알지 못하지만, 핸들 (handle)을 이용해서 방향을 조정하고 엑셀과 브레이크를 이용해서 속도를 제어할 수 있다는 것은 알 수 있다. 이처럼 운전자는 구지 자동차의 내부 동작 원리는 몰라도 운전을 하는데 아무런 지장이 없는 것과 캡슐화가 이와 같은 이치이다.
캡슐화는 클래스 내부에 여러 속성과 여러 기능을 함께 묶고 외부로부터 임의로 접근이 되지 못하게 하는 보호 장치라 할수 있다. 자바에서의 캡슐화의 기초는 클래스(class)이며, 이 클래스에 숨겨야 하는 정보(private)와 공개해야 하는 정보(public) 구분하여 기술할 수 있다. 사용자는 공개가 된 정보에만 접근이 가능하기에 정보의 은닉(Information Hiding)을 할 수 있게 된다.
캡슐화에 대해서 다시 정리를 하자면 아래와 같다.
- 객체의 속성, 메소드를 하나로 묶고, 실제 구현 내용을 외부에 숨기는 것을 말한다.
- 외부 객체는 객체 내부의 구조를 알지 못하며 객체가 공개를 하여 제공하는 속성과 메소드만 사용할 수 있다.
- 속성과 메소드를 캡슐화하여 보호하는 이유는 외부의 잘못된 사용으로 인해 객체가 손상되지 않도록 하는데 있다.
- 자바는 캡슐화된 멤버를 공개할 것인지 숨길 것인지를 결정하기 위해 접근 제한자(Access Modifier) 키워드를 사용한다.
다형성(polymorphism)
다형성은 하나의 인터페이스를 서로 다른게 구현을 하여 상황에 따라 다른 의미로 동작될 수 있는 것을 의미한다. 앞으로 배우게 될 오버라이딩(overriding)이 여기에 해당된다.
객체 지향 프로그래밍에서는 추상(abstract) 클래스로 먼저 생성하고 추상 클래스를 상속받아 하위 클래스가 상위 추상 클래스에서 정의한 추상 메소드를 재정의 즉, 오버라이딩한다. 또 다른 하위 클래스가 이 추상 클래스를 다시 상속을 받아 추상 메소드를 재정의를 하게 되었다고 하자. 이때 각 두개의 하위 클래스에서는 각자 추상 메소드를 재정의 했기에 호출 다른 행위를 할 수 있게 되는 것이다.
예를 들면, 모형이라는 추상 클래스가 있고 이를 상속 받은 삼각형, 사각형, 원형이 하위 클래스가 있다고 하자. 도형에서는 draw()이라는 추상 메소드가 있고 이를 각 하위 클래스가 상속을 하여 재정의를 하게 되면 똑같은 draw()를 했어도 하위 클래스가 무엇인가에 따른 다른 형태의 그림이 나오게 될 것이다.
모형 클래스는 하위 클래스에서 모형을 그리는데 사용될 수 있는 추상 draw 메소드를 가지고 있다. 이 추상 메소드를 각 삼각형, 사각형, 원형 클래스에서 재정의하여 각각 상속 받은 클래스 따라 메소드를 호출시에 다른 형위를 하게 된다.
참조
- http://hunit.tistory.com/151
- http://searchstory.tistory.com/entry/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90
- http://pacs.tistory.com/entry/C-%EC%83%81%EC%86%8D%EA%B3%BC-%EB%8B%A4%ED%98%95%EC%84%B1-Inheritance-Polymorphism