[Java] 객체지향 프로그래밍(OOP)
객체지향 프로그래밍(Object Oriented Programming)이란?
객체 지향 프로그래밍은 컴퓨터 프로그래밍 패러다임 중 하나로, 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
절차 지향
C언어는 절차 지향 프로그래밍 이라고 하며, 절차 지향 프로그래밍은 프로세스가 함수 단위로 순서대로 진행되는 것을 말합니다.
구분 | 절차 지향 프로그래밍 | 객체 지향 프로그래밍 |
---|---|---|
처리방식 | 문제를 여러 개의 함수로 나누어 순차적으로 호출하여 처리하는 방식 | 문제를 여러개의 객체 단위로 나누어 처리하는 방식 |
단점 | 오래된 방식이며 협업해서 진행하는 큰 프로젝트에는 적합하지 않음 | 학습 난이도가 높음, 개발자의 활용 능력이 중요함 |
장점 | 간단하고 소규모 프로젝트에 용이함, 비교적 배우기 쉬움 | 최근 가장 많이 사용하는 방식임, 협업이 중요한 대형 프로젝트에 적합함. |
객체 지향 프로그래밍의 장점
- 프로그램을 유연하고 변경이 용이하게 만든다.
- 프로그램의 개발과 보수를 간편하게 만든다.
- 직관적인 코드 분석을 가능하게 한다.
- 대형 프로젝트에 적합하다.
객체지향 프로그래밍의 단점
- 처리속도가 상대적으로 느리다.
- 객체가 많으면 용량이 커질 수 있다.
- 설계 시 많은 시간과 노력이 필요하다.
위의 장점들을 관통하는 객체 지향 프로그래밍의 중요한 특성은 강한 응집도(Strong Cohesion)
과 약한 결합도(Weak Coupling)
를 지향한다는 점이다.)
- 응집도(cohesion) : 프로그램의 한 요소가 해당 기능을 수행하기 위해 얼마만큼의 연관된 책임과 아이디어가 뭉쳐있는지를 나타내는 정도이다. 일반적으로 프로그램의 한 요소가 특정 목적을 위해 밀접하게 연관된 기능들이 무여서 구현되어 있고, 지나치게 많은 일을 하지 않으면 그것을 응집도가 높다고 표현한다. 응집도가 높으면 프로그램을 쉽게 이해할 수 있으므로 유지보수성이 높아진다.
- 응집도가 낮은 클래스의 문제점 :
- 이해하기 힘들다
- 재사용하기 힘들다.
- 유지보수가 힘들다.
- 다른클래스의 변화에 민감하다.
- 결합도(coupling) : 소프트웨어 코드의 한 요소가 다른 것과 얼마나 강력하게 연결되어 있는지, 또한 얼마나 의존적인지 나타내는 정도이다. 프로그램의 요소가 결합도가 낮다는 것은 그것이 다른 요소들과 관계를 그다지 맺지 않은 상태를 의미한다.
- 결합도가 높은 클래스의 문제점
- 연관된 다른 클래스가 변경되면 더불어 변경해야 한다.
- 수정하려는 클래스를 이해하기 위해 연관된 다른 클래스를 함께 이해해야 한다.
- 나중에 다른 프로그램에서 클래스를 재사용 하기도 힘들다.
- 결합도가 높은 클래스의 문제점
OOP의 기본 구성 요소
- 클래스(Class)
- 같은 종류의 집단에 속하는 속성과 행위를 정의한 것. 다른 클래스와 독립적으로 디자인해야함
클래스와 인스턴스(객체)의 차이
- 클래스 : 어떤 문제를 해결하기 위한 데이터를 만들기 위해 추상화를 거쳐 집단에 속하는 속성(attribute)과 행위(behavior)를 변수와 메서드로 정의한 것
- 인스턴스 : 클래스에서 정의한 것을 토대로 실제 메모리상에 할당된 것으로 실제 프로그램에서 사용되는 데이터
- 클래스는 클래스영역에 인스턴스는 힙영역에 저장된다.
- 객체(Object)
- 클래스의 인스턴스(Instance). 상위 클래스의 속성을 가지고 있으면서 개별적인 특성과 행위(메소드: Method)를 가지고 있다.
- 메서드(Method)
- 클래스로부터 생성된 사용하는 방법, 객체의 속성을 조작하는 데사용된다.
OOP의 특징
추상화
- 목적과 관련이 없는 부분을 제거하여 필요한 부분만을 표현하기 위한 개념.
- 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 공통의 속성이나 기능을 묶어 이름을 붙이는 것이다.
- 이는 객체지향 관점에서 클래스를 정의하는 것이고, abstract 클래스와 abstract 메서드와는 다른 이야기이다.
- 객체들의 공통된 특징을 파악해 정의해 놓은 설계 기법.
- 목적과 관련이 없는 부분을 제거하여 필요한 부분만을 표현하기 위한 개념.
캡슐화
- 목적 : 코드를 재수정 없이 활용하는 것이다.
- 프로그램 코드에서 변수와 함수를 재활용하기에는 분산되어 있기 때문에 재활용이 어려웠으나 캡슐화를 통해 관련된 기능과 특성을 한 곳에 모으고 분류하기 때문에 재활용이 원활해졌다.
- 연관있는 변수와 함수를 클래스로 묶는 작업.
- 객체 지향 프로그래밍에서 기능과 특성의 모음을 “클래스”라는 “캡슐”에 분류해서 넣는것이 캡슐화다.
- 객체가 맡은 역할을 수행하기 위한 하나의 목적을 한데 묶는다.
- 정보은닉을 할 수 있다.. 그렇다고 캡슐화 == 정보은닉은 아니다.
- 목적 : 코드를 재수정 없이 활용하는 것이다.
상속
- 자식 클래스가 부모 클래스의 멤버를 물려받는 것.
- 자식이 부모를 선택해서 물려 받는 것.
- 상속 대상: 부모의 필드와 메소드
- 상속의 효과
- 부모클래스를 재사용해서 자식 클래스를 빨리 개발할 수 있다.
- 반복된 코드의 중복을 줄여준다.
- 유지 보수의 편리성을 제공해 준다. (부모클래스를 한번만 수정함으로써 자식클래스를 수정할 필요가 없음)
- 객체의 다형성을 구현할 수 있다.
다형성
같은 타입이지만 실행결과가 다양한 객체를 대입(이용) 할 수 있는 성질.
하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것이다.
즉 오버라이딩(Overriding), 오버로딩(Overloading)이 가능하다는 얘기다.
오버라이딩 : 부모클래스의 메서드와 같은 이름, 매개변수를 재정의 하는것.
오버로딩 : 같은 이름의 함수를 여러개 정의하고, 매개변수의 타입과 개수를 다르게 하여 매개변수에 따라 다르게 호출할 수 있게 하는 것.
부모 타입에는 모든 자식 객체가 대입될 수 있으며 자식 타입은 부모 타입으로 자동 타입변환이 됩니다.
인터페이스와 상속은 둘 다 다형성이라는 객체지향 프로그래밍의 특징을 구현하는 방식이다.
추가 : getter, setter 를 사용하는 이유?
메서드를 통해서 접근하기 때문에, 메서드 안에서 매개변수같이 어떤 올바르지 않은 입력에 대해 사전에 처리할 수 있게 제한하거나 조절할 수 있기 때문
예를들면 setter에서 유효범위를 넘은 정수가 들어왔을 때의 처리를 하고나서 set하거나 예외처리를 해버릴 수 있는 것이다. getter도 마찬가지로 굳이 예를들자면 자료에 무언가 더하거나 빼고 준다든지가 가능하다.
객체 지향적 설계 원칙의 종류(SOLID)
- SRP(Single Responsibility Principle) : 단일 책임 원칙 클래스는 단 하나의 책임을 가져야 하며 클래스를 변경하는 이유는 단 하나의 이유이어야 합니다.
- OCP(Open-Closed Principle) : 개방-폐쇄 원칙 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 합니다.
- LSP(Liskov Substitution Principle) : 리스코프 치환 원칙 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 합니다.
- ISP(Interface Segregation Principle) : 인터페이스 분리 원칙 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 합니다.
- DIP(Dependency Inversion Principle) : 의존 역전 원칙 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안됩니다.
Reference
- https://velog.io/@cyranocoding/객체-지향-프로그래밍OOP-Object-Oriented-Programming-개념-및-활용-정리-igjyooyc6c
- https://victorydntmd.tistory.com/117
- https://lazineer.tistory.com/93
- https://webclub.tistory.com/156
- https://webclub.tistory.com/155
- https://jeong-pro.tistory.com/95