📄 OOP(Object Oriented Programming)은 무엇일까?
영어를 그대로 해석한다면 Object(객체) Oriented(지향) 프로그래밍 즉, 객체 지향 프로그래밍의 영어를 약자로 적어 놓을것이다.
그렇다면 객체 지향 프로그래밍은 무엇일까? 바로 인간 중심적 프로그래밍이라고 할 수 있다. 현실 세계의 사물을 객체라고 보고 객체를 기준으로 코드로 나누어 구현한다. 대표적으로 OOP를 지키며 개발하는 것이 바로 Java이다.
Java의 클래스는 전체적인 설계도를 뜻하고 직접적으로 일을 하는 것이 바로 인스턴스이다.
그래서 자바는 OOP라고 해도 틀리지 않은 것이다..
장점
- 다른 클래스를 가져와 사용할 수 있고 상속받을 수 있어 코드의 재사용성이 증가하낟
- 자주 사용되는 로직을 하나의 라이브러리로 만들어두면 계속해서 사용할 수 있다
- 클래스 단위의 모듈화가 가능
- 디버깅이 쉽고 유지보수가 용이하다
단점
- 객체가 많으면 용량이 커지고 처리 속도가 상개적으로 느려진다.
- 설계 시 많은 노력과 시간이 필요하다.
📄 OOP 특징
캡슐화 (Encasulation)
하나의 객체에 대해 그 객체가 특정한 목적을 위한 필요한 변수나 메소드를 하나로 묶는 것을 의미한다.
♪ 정보 은닉
캡슐화의 중요한 목적은 바로 정보 은닉이다.
접근 제어자에 따라 데이터를 보호해서 접근을 제한할 수 있고 이어서 getter와 setter 등으로 메소드를 통해 직접적으로 접근이 불가능하도록 하는 것이 캡슐화의 주 목적이기도 하다.
캡슐화 == 정보은닉(???)
굉장히 비슷할 수 있지만 정확히 같은 개념이 아니다. 캡슐화를 하기에 정보은닉이 가능하다 라고 생각해야 한다.
추상화 (Abstraction)
불필요한 정보 외 중요한 정보만 표현함으로써 공통의 속성과 기능을 묶어 이름을 붙이는 것이다.
세상의 물건을 객체로 보지만 모든 것을 담을 수는 없다. 때문에 공통적인 요소나 특징을 추출하는 과정이 필요하다고 느낀 것이다.
예를 들어 보면 세상엔 정말 다양한 자동차의 종류가 있지만 공통적으로 보이는 부품이 있다. 운전 방향, 바퀴, 문짝의 갯수 등등 이러한 공통적인 부분을 필수로 보기때문에 이것을 추출하는 과정인 것이다.
이렇게 추출한 것을 추상적으로 만들어 클래스로 만들어낸것이 추상클래스이다.
즉, 추상화는 객체들의 공통된 특징을 파악해 정의해 놓은 설계 기법이라고 한다
다형성 (Polymorphism)
형태가 같은데 다른 기능(다른 결과물)을 하는 것을 의미한다.
- 치킨집을 클래스화하고 "배달"이라는 속성이 정의되어 있다
- 배달 주문을 자동차로 하는 치킨가게인 클래스가 치킨집에 있는 배달이 자동으로 상속된다
두개의 주문을 하는 행위는 같지만 배달이 가능한 치킨집은 배달이 되는 방식이 다르다는 것이다.
대표적인 다형성 (Override & Overload)
- Override
- 부모 클래스에서 상속받은 자식 클래스에서 부모 클래스에서 만들어진 메소드를 자식 클래스에서 자신의 입맛대로 다시 재정의해서 사용하는것을 말한다.
- Overload
- 같은 이름의 메소드를 사용하지만 메소드마다 다른 용도로 사용되며 그 결과물도 다르게 구현할 수 있게 만드는 개념이다.
상속화 (Inheritance)
클래스로부터 속성과 메소드를 물려받아 수정할 일이 생긴다면 변경하고자 하는 부분만 변경한다.
실제 세계에서도 부모로부터 여러 가지를 상속받는다. OOP에서도 동일시 한다고 생각하면 된다.
이를 부모 클래스와 자식 클래스로 표현한다.
예를 들어 개 클래스와 고양이 클래스가 있다면 둘은 공통적인 특징인 포유류에 해당된다. 때문에 포유류의 속성들로 클래스를 만들고 개와 고양이 클래스에 물려주어 상속 관계로 만드는 것이다.
왜 상속을 해야할까?
코드의 중복을 없애기 위해 상속을 한다. 중복은 개발에서 피해야하는 굉장히 중요한 요소이다.
위에서 얘기했던 내용에서도 포유류라는 큰 범위의 클래스를 상속받으면서 포유류의 특징을 굳이 코드로 작성하지 않아도 되는 것에 따라 중복을 없앨수 있다.
하지만 코드의 중복을 완전히 없애는 방법은 되지 못한다.
📄 OOP의 5가지 설계 원칙 (SOLID)
SRP(Single Responsibility Principle)
단일 책임 원칙
- 클래스는 단 하나의 책임을 가지고, 그에대한 책임을 가져야한다.
OCP(Open Close Principle)
개방 - 폐쇄의 원칙
- 확장에는 열려있어야 하고 변경에는 닫혀있어야한다
- 확장을 하기 위해서는 클래스를 상속하여 새롭게 작성하여 확장을 하고 기존의 코드는 수정하지 않아야한다.
예를 들어 어떠한 무언가를 validation하는 코드가 작성된다면 조건이 추가될때마다 if else 문이 무한적으로 증가하게 된다. 이처럼 수정이 빈번하게 일어나고 가독성이 전체적으로 하락하는 현상이 발생할 수 있다.
해결책으로 interface 클래스인 validation을 만들고 검증의 조건이 추가 될때마다 해당 클래스를 override하여 구현하면 된다. 추후엔 inteface클래스를 인스턴스하는 것으로 모든 클래스를 사용할 수 있다.
LSP(Liskov Substitution Principle)
리스 코프 치환의 원칙
- 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야한다
- 자식 클래스를 사용중에 거기에 부모 클래스로 치환을 하더라도 문제가 없어야 한다.
LSP는 사각형의 넓이를 구하는 공식이 대표적인 예다.
사각형의 넓이를 구하는 공식은 높이 X 폭 이고 이는 정사각형이 되더라도 같은 공식이다. 하지만 사각형의 범위와 정사각형의 범위가 다르기때문에 비본질적으로는 다르다는 것을 알 수 있다
LSP는 OSP와 굉장히 헷갈리는 상황이 발생하는데 OCP가 만족이 된다면 자연스레 LCP가 만족됩니다.
ISP(Interface Segregation Principle)
인터페이스 분리의 원칙
- 각 행위에 대한 인터페이스는 모두 분리되어 있어야 한다.
복합기로 프린트를 하려고 하는데 다른 기능이 방해하지 않도록 하는것
SRP와 굉장히 비슷한 개념이기 때문에 ISP는 SRP를 지키면 자연스레 지켜지기도 한다.
DIP(Dependency Inversion Principle)
의존 역전의 원칙
- 추상화에 의존하는 것이지 구체화에 의지해서는 안된다
OCP원칙에서도 언뜻 나왔던 내용을 보면 구현체에 의존하면 해당 서비스를 사용하는 구현체가 변경이 될 때마다 변경시켜주어야 한다. 이는 굉장히 불편한 서비스로 이어지기 때문에 추상화에 의존을 해야 매번 수정을 하지 않을 수 있다.
📄 참고
'CS > 📝 언어' 카테고리의 다른 글
🖨 new String() 과 ""의 차이 (0) | 2024.06.04 |
---|---|
🖨 절차 지향과 객체 지향 프로그래밍의 차이 (0) | 2024.05.22 |
추상 클래스와 인터페이스의 차이 (0) | 2023.10.26 |
Java의 컴파일 과정 & JVM의 구조 (0) | 2023.10.18 |
JIT 컴파일러 와 인터프리터 (0) | 2023.10.18 |