객체 지향 프로그래밍(Object Oriented Programming)

  • 프로그램 설계 방법론
  • 명령형 프로그래밍 : 프로그램 상태에 대한 문장들을 작성하는 스타일
  • 초기 프로그래밍 방식인 절차적 프로그래밍에서 복잡한 순서도를 가진 코드의 문제점을 해결하기 위해 구조적 프로그래밍 방식이 생겨났다.
  • 하지만 데이터의 구조화는 하지 못했기 때문에 전역 네임스페이스 포화 문제, 실행 콘텍스트를 저장할 방법이 없는 문제 등등 여러 문제들이 있었다.
  • 객체 지향 프로그래밍으로, 큰 문제를 작게 쪼개는 것이 아니라 먼저 작은 문제를 해결할 수 있는 객체를 만든 후, 객체를 조합해서 큰 문제를 해결하는 상향식(Bottom-up) 방식을 도입했다.
  • 객체 지향 프로그램이 복잡해지면서 간결하게 정리할 수 있는 디자인 패턴이 생겼다.
    • 디자인 패턴 : 프로그래밍 형식을 정하는 일종의 약속
  • 객체 지향 프로그래밍은 객체가 상태를 갖기 때문에, 변수가 존재하고 이 변수를 통해 객체가 예측할 수 없는 상태를 갖게 되어 애플리케이션 내부에서 버그를 발생시킨다는 단점이 있다. -> 함수형 프로그래밍

 

객체 지향 프로그래밍의 요소

  • 캡슐화(encapsulation)
    • 변수와 함수를 하나의 단위로 묶는 것
    • 해당 클래스의 인스턴스 생성을 통해 클래스 안에 포함된 멤버 변수와 메소드에 쉽게 접근할 수 있다.
    • 정보 은닉(information hiding) : 응집도를 높이고, 결합도를 떨어트려 유연함과 유지보수 향상
  • 상속(inheritance)
    • 자식 클래스가 부모 클래스의 특성과 기능을 그대로 물려받는 것
    • 오버라이딩(Overriding) : 자식 클래스에서 상속받은 기능을 재정의
  • 다형성(polymorphism)
    • 하나의 변수, 또는 함수가 상황에 따라 다른 의미로 해석될 수 있는 것 
    • 서브타입 다형성(subtype polymorphism)
      • 기초 클래스나 인터페이스를 구현하는 상위 클래스를 생성해서, 해당 클래스를 상속받는 다수의 하위 클래스들을 만들어 상위 클래스의 포인터나 참조 변수들이 하위 클래스의 객체를 참조하게 하는 것
      • 상속받은 상위 클래스의 메소드를 하위 클래스에서 재정의해서 사용할 수 있다. -> 오버라이딩
    • 매개변수 다형성(parametric polymorphism)
      • 타입을 매개변수로 받아 새로운 타입을 되돌려주는 기능
      • 데이터 타입이나 함수를 범용적으로 작성하여 세부 타입에 상관없이 동일하게 처리 가능
      • 제네릭(generic)
        • 지정한 타입 매개변수에 해당하는 타입만 사용하겠다고 약속하는 방식
    • 임시 다형성(ad hoc polymorphism)
      • 함수 오버로딩(function overloading)
        • 같은 이름의 함수를 매개 변수의 개수 또는 타입을 변경하여, 여러 개의 함수가 서로 다르게 행동할 수 있는 성질
        • 잦은 함수 오버로딩은 전체적은 코드의 유지보수가 어렵기 때문에, 템플릿이나 제네릭으로 대체한다.
      • 연산자 오버로딩(operator overloading)
    • 강제 다형성(coercion polymorphism)
      • 묵시적 형변환(implicit type coercion)
      • 명시적 형변환(explicit type coercion)
double a = 30;
// int형 값 30은 double으로 묵시적 형변환

double a = (double)30;
// 결과는 위와 동일하지만, (double)을 통해 int형 값 30이 double으로 변환

 

 

객체 지향적 설계 원칙

  • SPR(Single Responsibility Principle) : 단일 책임 원칙
    • 클래스는 단 하나의 책임을 가진다. 클래스를 변경하는 이유는 단 하나의 이유이어야 한다.
  • OCP(Open-Closed Principle) : 개방-폐쇄 원칙
    • 확장에는 열려 있고, 변경에는 닫혀 있어야 한다.
  • LSP(Liskov Substitution Principle) : 리스코프 치환 원칙
    • 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
  • ISP(Interface Segregation Princinple) : 인터페이스 분리 원칙
    • 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.
  • DIP(Dependency Inversion Principle) : 의존 역전 원칙
    • 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.

+ Recent posts