객체 지향 프로그래밍(영어: Object-Oriented Programming, OOP)은 컴퓨터 프로그래밍의 패러다임 중 하나이다. 객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다. 출처:위키백과
오브젝티브-C
C++
c#
자바
델파이
파이썬
펄
루비
ASP
스위프트
등등
객체(Object)
실세계의 개념이나 논리적 개체를 프로그래밍에서 표현한 것으로, 데이터와 그 데이터에 대한 동작을 하나의 단위로 묶은 것입니다. 예를 들어, 자동차 객체는 속성(예: 색상, 속도)과 메서드(예: 가속, 제동)를 가질 수 있습니다.
클래스(Class)
객체를 생성하기 위한 청사진(템플릿)입니다. 클래스는 객체의 구조와 동작을 정의합니다. 예를 들어, 자동차 클래스는 모든 자동차 객체가 공통적으로 가지는 속성과 메서드를 정의합니다.
캡슐화(Encapsulation)
객체의 내부 상태를 외부에서 직접 접근하지 못하게 하고, 오직 메서드를 통해서만 접근할 수 있도록 하는 원칙입니다. 이를 통해 객체 내부의 상태를 보호하고, 복잡성을 줄일 수 있습니다.
상속(Inheritance):
기존 클래스(부모 클래스)의 속성과 메서드를 새로운 클래스(자식 클래스)에서 재사용하고 확장하는 개념입니다. 예를 들어, 차량이라는 부모 클래스를 상속받아 자동차, 트럭, 오토바이 등의 자식 클래스를 만들 수 있습니다.
다형성(Polymorphism)
같은 이름의 메서드가 다른 클래스에서 다르게 동작하도록 하는 능력입니다. 이는 메서드 오버로딩이나 메서드 오버라이딩을 통해 구현됩니다. 예를 들어, 동물 클래스에 소리내기라는 메서드가 있다면, 개 클래스에서는 멍멍, 고양이 클래스에서는 야옹과 같이 다른 방식으로 동작할 수 있습니다.
ex)자바의 오버로드(Overload) 또는 오버라이드(Override)이 다형성의 대표적인 예라 할 수있다
재사용성: 잘 설계된 클래스는 다른 프로젝트에서 재사용이 가능합니다.
유지보수성: 코드 수정이 필요한 경우, 해당 객체나 클래스만 수정하면 되므로 유지보수가 용이합니다.
확장성: 새로운 기능이 필요할 때 기존 코드를 수정하지 않고도 새로운 클래스를 추가함으로써 시스템을 확장할 수 있습니다.
모듈성: 프로그램을 여러 개의 객체로 분리하여, 각각의 객체를 독립적으로 개발하고 테스트할 수 있습니다.
객체지향 프로그래밍은 Java, C++, Python 등 다양한 프로그래밍 언어에서 널리 사용되며, 소프트웨어 개발의 효율성을 높이는 데 중요한 역할을 합니다.
초기 설계의 어려움:초기 설계의 어려움: 객체지향 설계는 초기 설계 단계에서 많은 고민과 계획이 필요합니다. 클래스와 객체 간의 관계를 설계하는 것이 복잡할 수 있으며, 설계가 잘못되면 코드 유지보수가 어려워질 수 있습니다.
과잉 설계(over-engineering): 단순한 문제를 해결하는 데도 복잡한 클래스를 설계하게 되면, 오히려 코드가 불필요하게 복잡해질 수 있습니다. 모든 것을 객체로 표현하려는 경향이 과잉 설계로 이어질 수 있습니다.
추상화로 인한 오버헤드: 객체지향 프로그래밍에서는 메서드 호출과 상속 등으로 인해 함수 호출 오버헤드가 발생할 수 있습니다. 이러한 오버헤드는 성능에 영향을 미칠 수 있으며, 특히 성능이 중요한 시스템에서는 문제가 될 수 있습니다.
메모리 사용 증가: 객체지향 시스템에서는 많은 객체가 생성되고 이들이 메모리를 점유합니다. 객체가 많이 생성되면 메모리 관리가 어려워지고, 성능 저하로 이어질 수 있습니다.
개념의 복잡성: 객체지향 프로그래밍의 개념(예: 캡슐화, 상속, 다형성)은 초보자에게 이해하기 어려울 수 있습니다. 특히, 객체 간의 복잡한 관계나 다형성 같은 개념은 학습 초기 단계에서 혼란을 줄 수 있습니다.
추상화와 패턴의 이해: 디자인 패턴, 추상화, 인터페이스 등 객체지향 프로그래밍의 고급 개념을 제대로 이해하고 적용하는 데 시간이 걸립니다.
고정된 구조: 객체지향 프로그래밍은 클래스 구조가 고정되어 있는 경우가 많아, 변화하는 요구사항에 유연하게 대응하기 어려울 수 있습니다. 특히 상속 구조가 깊어질수록 변화에 취약해지며, 수정 시 영향 범위가 넓어집니다.
상속의 남용: 상속은 강력한 도구지만, 잘못 사용하면 코드의 유연성을 제한하고, 유지보수를 어렵게 만들 수 있습니다. 상속이 많아지면, 부모 클래스의 변화가 자식 클래스에 의도치 않은 영향을 줄 수 있습니다.
디버깅의 어려움: 다형성(polymorphism)을 사용할 때, 메서드 오버라이딩(overriding)으로 인해 특정 메서드가 실제로 어떤 클래스에서 호출되는지 추적하기 어려울 수 있습니다. 이는 디버깅을 복잡하게 만들 수 있습니다.
잘못된 재사용: 객체지향 프로그래밍은 재사용성을 강조하지만, 클래스가 다른 환경이나 문맥에서 재사용될 때 의도치 않은 문제를 일으킬 수 있습니다. 재사용을 위해 무리하게 일반화하면 오히려 코드가 복잡해지고 유지보수가 어려워질 수 있습니다.
이와 같은 이유로, 객체지향 프로그래밍은 모든 상황에 적합하지 않을 수 있으며, 문제의 성격에 따라 절차지향 프로그래밍, 함수형 프로그래밍 등 다른 프로그래밍 패러다임을 고려해야 할 때도 있습니다.