본문 바로가기
프로그래밍/일반

객체지향 프로그래밍의 개념과 특징, 그리고 설계원칙

by 불타는홍당무 2015. 1. 28.

 

※ 이 글은 키백과와 cjmyun.tripod.com, chs02.tistory.com을 참고하여 작성하였습니다.

 

 

객체지향 프로그래밍(OOP: Object-Oriented Programming)이란? 

 

현재 가장 활발하게 쓰이는 컴퓨터 프로그래밍 패러다임 중 하나이다. 객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다.


 

[구성요소] 


클래스(Class) : 같은 종류(또는 문제 해결을 위한)의 집단에 속하는 속성(변수)과 행위(메소드)를 정의한 것으로 객체지향 프로그램의 기본적인 사용자 정의 데이터형(user define data type)이라고 할 수 있다. 클래스는 프로그래머가 아니지만 해결해야 할 문제가 속하는 영역에 종사하는 사람이라면 사용할 수 있고, 다른 클래스 또는 외부 요소와 독립적으로 디자인하여야 한다.

 

객체(Object) : 클래스의 인스턴스(실제로 메모리상에 할당된 것)이다. 즉 클래스라는 일종의 설계도를 기반으로 실제로 생성된 그 실체가 바로 객체이다. 객체는 자신 고유의 속성(attribute)을 가지며 클래스에서 정의한 행위(behavior)를 수행할 수 있다. 

 

메서드(Method)와 메시지(Message) : 클래스로부터 생성된 객체를 사용하는 방법으로서 객체에 명령을 내리는 행위라고 할 수 있다. 메서드는 한 객체의 서브루틴(subroutine) 형태로 객체의 속성을 조작하는 데 사용된다. 메시지는 객체간의 통신이 이루어지는 방법이며 이 메시지를 통해 메소드가 호출되어 사용된다.

 

*속성(attribute) = 변수(variable) / 행위(behavior/operation) = 메소드(method) = 함수(function)


[객체지향의 특징]

 

1. 추상화(Abstraction)


객체에서 공통된 속성과 행위를 추출하는 것을 추상화(Abstraction)라고 한다. 


예를 들어 홍길동 교수, 이순신 교수, 강감찬 교수가 있다고 하자.

이 교수들을 기반으로 공통된 속성과 행위로 추출하여 '교수'라는 클래스를 정의한다고 생각해보자.

공통된 속성으로 이름, 주민번호, 강의분야, 주소, 전화번호를 선언하고, 

공통된 행위로 '강의하다', '채점하다', '과정 등록하다'를 선언했다고 하면, 다음과 같은 클래스가 만들어진다.

위와 같은 이러한 과정을 바로 '추상화'라고 한다. 


2. 캡슐화(Encapsulation)

 

객체의 상세한 내용을 객체 외부에 철저히 숨기고 단순히 메시지만으로 객체와의 상호작용을 하게 하는 것을 캡슐화(encapsulation)라고 한다. 정보 은닉(information hiding)이라는 표현으로 설명하기도 하는데 추상화와 동일한 개념이다. 캡슐화는 추상화와 거의 같은 개념이지만 추상화를 지원하며 보다 구체적이고 제한적이라고 할 수 있다.

예를 들면, 클래스를 선언하고 그 클래스를 구성하는 객체에 대하여 "public" 또는 "private" 등으로 정의해준다. 이렇게 되면 "public"으로 정의된 함수 또는 데이터는 외부에서 사용이 가능하며, "private"으로 선언된 경우는 외부에서 제어할 수 없고 내부에서만 사용된다.

이것은 클래스 외부에는 제한된 접근 권한을 제공하며 원하지 않는 외부의 접근에 대해 내부를 보호하는 작용을 한다. 이렇게 함으로써 이들 부분이 프로그램의 다른 부분들에 영향을 미치지 않고 변경될 수 있다.

 

3. 상속(Inheritance)

 

상속은 클래스의 속성과 행위를 하위 클래스에 물려주거나, 상위 클래스에서 물려받는 것을 지칭한다.

 

*상속을 사용하면 좋은점은?


  • 재사용으로 인한 코드가 줄어든다. 하위 클래스에서 속성이나 행위를 다시 정의하지 않고 상속 받아서 사용함으로써 코드가 줄어든다. 
  • 좀 더 범용성 있게 사용할 수 있다. 예를 들어 Object타입의 매개변수에는 String타입이나 int타입의 객체가 쓰여도 문제되지 않는다. 왜냐하면 String과 int타입 모두 Object타입의 객체를 상속받은 하위 클래스이기 때문이다.


참고로 하위 클래스는 상위 클래스가 가지고 있는 모든 자료와 메소드를 물려받아 자유롭게 사용할 수 있지만, 또한 자신만의 자료와 메소드를 추가적으로 덧붙임으로써 새로운 형태의 클래스로 발전할 수 있다.

 

4. 다형성(Polymorphism)

 

다형성은 객체지향의 개념에서 가장 중요한 특징이라고 말할 수 있다. 다형성이란 사전적 의미로 '다양한 형태로 나타날 수 있는 능력'을 뜻한다.

 

객체지향 프로그래밍은 하나의 클래스 내부에 같은 이름의 행위를 여럿 정의하거나, 상위 클래스의 오퍼레이션을 하위 클래스에서 다시 정의하여 사용할 수 있기 때문에 바로 이 다형성이라는 특징을 갖는 것이다.

 

※ 객체지향 프로그래밍에서 다형성 구현방법


메소드 오버로딩: 클래스 내부에 동일한 이름의 행위를 여럿 정의하는 것.


  • 함수명은 같아야 한다.
  • 파라미터의 타입과 개수는 서로 달라야 한다.
  • 리턴타입은 관계없다.


장점) 메소드 이름의 낭비 방지, 같은 메소드에 여러 종류의 매개변수를 받을 수 있음




- 메소드 오버라이딩: 상속으로 물려받은 자료나 메소드를 그대로 사용하지 않고 자신이 새로 만들어 사용하는 것.

  • 함수명은 같아야 한다.
  • 파라미터의 타입과 개수는 동일해야 한다.
  • 리턴타입은 같아야 한다.


장점) 코드의 재사용성 향상 



 

 

[객체지향의 설계 원칙]

 

1. 단일 책임의 원칙(SRP: The Single Responsibility Principle)


단일 책임의 원칙이란 '하나의 클래스에는 한 가지 종류의 책임(혹은 기능)을 두어야 한다'는 원칙이다. 이는 각 클래스의 Cohesion(응집력)을 높이기 위함이다.

 

2. 개방/폐쇄의 원칙(OCP: The Open-Closed Principle)


개방/폐쇄의 원칙은 '확장에 대해서는 개방되어야 하지만, 변경에 대해서는 폐쇄되어야 한다'는 원칙이다. 이러한 원칙을 통해 얻고자 하는 것은 기능을 확장했을 때, 기존 클래스의 변경을 최소화하는 것이다. 이는 디자인 패턴을 적용하는 이유이기도 하다.


3. 인터페이스 분리의 원칙(ISP: Interface Segregation Principle)

 

인터페이스 분리의 원칙은 '클라이언트는 자신이 사용하지 않는 메소드와 의존 관계를 갖지 않도록 해야 한다'는 원칙이다. 이는 각 메소드의 변경에 따른 클래의 변경을 최소화하자는데 있다.

 

4. 리스코프 치환의 원칙(LSP: Liskov Substitution Principle)


리스코프 치환의 원칙은 '서브타입은 언제나 기반타입으로 대체할 수 있어야 한다'는 원칙이다.


5. 의존 관계 역전의 원칙(DIP: Dependency Inversion Principle)

 

의존 관계 역전의 원칙은 '고차원 모듈은 저차원 모듈에 의존하면 안 된다'는 원칙이다. 한 마디로 말하면 추상클래스나 인터페이스를 쓰라는 말이다. 일반적으로 추상 클래스와 인터페이스를 변경하기보다는 콘크리트 클래스를 변경해야 되는 경우가 더 많이 있다. 그러나 콘크리트 클래스에 의존하면 그 클래스에 의존하는 클래스를 수정해야 하는 경우가 많기 때문에 추상클래스나 인터페이스에 의존할 것을 권고하는 원칙이다.