0. 객체지향 프로그래밍(OOP)이란?
프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 '객체'를 만들고,
그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
💡 객체란?
→ 객체란 하나의 역할을 수행하는 '메소드와 변수(데이터)'의 묶음
※ 참고 : OOP란?
→ Object-Oriented Programming
1. 객체지향의 장단점
➕ 장점
▶ 코드 재사용이 용이
남이 만든 클래스를 가져와서 이용할 수 있고 상속을 통해 확장해서 사용할 수 있음.
▶ 유지보수가 쉬움
절차 지향 프로그래밍에서는 코드를 수정해야할 때 일일이 찾아 수정해야하는 반면,
객체 지향 프로그래밍에서는 수정해야 할 부분이 클래스 내부에 멤버 변수 혹은
메서드로 존재하기 때문에 해당 부분만 수정하면 됨.
▶ 대형 프로젝트에 적합
클래스 단위로 모듈화시켜서 개발할 수 있으므로
대형 프로젝트처럼 여러 명, 여러 회사에서 프로젝트를 개발할 때 업무 분담하기 쉬움.
➖ 단점
▶ 처리 속도가 상대적으로 느림
▶ 객체가 많으면 용량이 커질 수 있음
▶ 설계시 많은 시간과 노력이 필요
2. 객체 지향 프로그래밍의 특징
1. 클래스 + 인스턴스(객체)
클래스란?
→ 어떤 문제를 해결하기 위한 데이터를 만들기 위해 추상화를 거쳐
집단에 속하는 속성(attribute)과 행위(behavior)를 변수와 메서드로 정의한 것
인스턴스(객체)란?
→ 클래스에서 정의한 것을 토대로 실제 메모리에 할당된 것으로 실제 프로그램에서 사용되는 데이터
2. 추상화(Abstraction)
필요로 하는 속성이나 행동을 추출하는 작업
🚨 여기서 말하는 추상화는 추상 클래스나 추상 클래스가 갖는 추상 메서드를 의미하기보다는 클래스를 설계하는 것 자체를 의미한다. → 즉, '공통의' 속성이나 기능을 묶어 이름을 붙이는 것.
ex. 아우디, BMW, 벤츠는 모두 '자동차'라는 공통점이 있다.
자동차라는 추상화 집합을 만들어두고, 자동차들이 가진 공통적인 특징들을 만들어 활용한다.
☑️ 왜 필요할까? → 예를 들면, '현대'와 같은 다른 자동차 브랜드가 추가될 수도 있다. 이때 추상화로 구현해두면 다른 곳의 코드는 수정할 필요 없이 추가로 만들 부분만 새로 생성해주면 된다.
3. 캡슐화(Encapsulation)
낮은 결합도를 유지할 수 있도록 설계하는 것.
→ 즉, 한 곳에서 변화가 일어나도 다른 곳에 미치는 영향을 최소화 시키는 것
(객체가 내부적으로 기능을 어떻게 구현하는지 감춤)
☑️ 결합도가 낮도록 만들어야 하는 이유가 무엇일까?
💡 결합도(coupling)란?
→ 어떤 기능을 실행할 때 다른 클래스나 모듈에 얼마나 의존적인가를 나타내는 말
즉, 독립적으로 만들어진 객체들 간의 의존도가 최대한 낮게 만드는 것이 중요하다.
객체들 간의 의존도가 높아지면 굳이 객체 지향으로 설계하는 의미가 없어짐.
※ 소프트웨어 공학에서의 요구사항 변경에 대처하는 좋은 설계 방법은?
→ 객체 안의 모듈 간의 요소가 밀접한 관련이 있는 것으로 구성하여
응집도를 높이고, 결합도를 줄여야 함.
☑️ 캡슐화는 어떻게 높은 응집도와 낮은 결합도를 갖게 할까?
정보 은닉을 활용한다!
💡 정보 은닉이란?
→ 외부에서 접근할 필요가 없는 것들은 private으로 접근하지 못하도록 제한을 두는 것
4. 상속
클래스의 속성과 행위를 하위 클래스에 물려주거나,
하위 클래스가 상위 클래스의 속성과 행위를 물려받는 것을 말함.
새로운 클래스가 기존의 클래스의 데이터와 연산을 이용할 수 있게 하는 기능
💡 상속이란?
→ 부모클래스의 속성과 기능을 그대로 이어받아 사용할 수 있게하고,
기능의 일부분을 변경해야 할 경우 상속받은 자식클래스에서 해당 기능만 다시 수정(정의)하여 사용할 수 있게 하는 것
➖ 상속 재사용의 단점
▶ 상위 클래스(부모 클래스)의 변경이 어려워진다.
부모 클래스에 의존하는 자식 클래스가 많을 때, 부모 클래스의 변경이 필요하다면?
이를 의존하는 자식 클래스들이 영향을 받게 된다.
▶ 불필요한 클래스가 증가할 수 있다.
유사기능 확장시, 필요 이상의 불필요한 클래스를 만들어야 하는 상황이 발생할 수 있다.
▶ 상속이 잘못 사용될 수 있다.
_같은 종류가 아닌 클래스의 구현을 재사용_하기 위해 상속을 받게 되면, 문제가 발생할 수 있다.
상속 받는 클래스가 부모 클래스와 IS-A 관계가 아닐 때 이에 해당한다.
(※ IS-A 관계 (is a relationship) : '~은 ~이다.'로 상속관계를 의미)
🔆 해결책은?
객체 조립(Composition), 컴포지션이라고 부르기도 한다.
객체 조립은, 필드에서 다른 객체를 참조하는 방식으로 구현된다.
상속에 비해 비교적 런타임 구조가 복잡해지고, 구현이 어려운 단점이 존재하지만
변경 시 유연함을 확보하는데 장점이 매우 크다.
따라서 같은 종류가 아닌 클래스를 상속하고 싶을 때는 객체 조립을 우선적으로 적용하는 것이 좋다.
☑️ 그럼 상속은 언제 사용?
- IS-A 관계가 성립할 때
- 재사용 관점이 아닌, 기능의 확장 관점일 때
4. 다형성(Polymorphism)
하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것
⭐ 객체 지향의 핵심과도 같은 부분
다형성은, 상속과 함께 활용할 때 큰 힘을 발휘한다.
→ 즉, 부모 클래스의 메소드를 자식 클래스가 오버라이딩해서 자신의 역할에 맞게 활용하는 것이 다형성
💡 오버라이딩이란?
→ 부모클래스의 메서드와 같은 이름, 매개변수를 재정의 하는 것
💡 오버로딩이란?
→ 같은 이름의 함수를 여러개 정의하고, 매개변수의 타입과 개수를 다르게 하여 매개변수에 따라 다르게 호출할 수 있게 하는 것
3. getter, setter 를 사용하는 이유
메서드를 통해서 접근하기 때문에,
메서드 안에서 매개변수같이 어떤 올바르지 않은 입력에 대해
사전에 처리할 수 있게 제한하거나 조절할 수 있기 때문
4. 객체 지향 설계 과정
- 제공해야 할 기능을 찾고 세분화한다. 그리고 그 기능을 알맞은 객체에 할당한다.
- 기능을 구현하는데 필요한 데이터를 객체에 추가한다.
- 그 데이터를 이용하는 기능을 넣는다.
- 기능은 최대한 캡슐화하여 구현한다.
- 객체 간에 어떻게 메소드 요청을 주고받을 지 결정한다.
5. 객체 지향 설계 원칙 (SOLID)
1. 단일 책임 원칙
(SRP, Single Responsibility Principle)
- 하나의 클래스는 단 하나의 책임만 가져야 한다.
- 클래스를 변경하는 이유는 단 한개여야 한다.
🚨 이를 지키지 않으면, 한 책임의 변경에 의해 다른 책임과 관련된 코드에 영향이 갈 수 있다.
2. 개방-폐쇄 원칙
(OCP, Open/Closed Principle)
- 소프트웨어 요소는 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다.
- 기능을 변경하거나 확장할 수 있으면서 기능을 사용하는 코드는 수정하지 않는다.
3. 리스코프 치환 원칙
(LSP, Liskov Substitution Principle)
- 상위 타입의 객체를 하위 타입의 객체로 치환해도,
상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
🚨 상속 관계가 아닌 클래스들을 상속 관계로 설정하면, 이 원칙이 위배된다.
4. 인터페이스 분리 원칙
(ISP, Interface Segregation Principle)
- 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.
- 각 클라이언트가 필요로 하는 인터페이스들을 분리함으로써,
각 클라이언트가 사용하지 않는 인터페이스에 변경이 발생하더라도
영향을 받지 않도록 만들어야 한다.
5. 의존관계 역전 원칙
(DIP, Dependency Inversion Principle)
- 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.
- 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다.
→ 즉, 저수준 모듈이 변경돼도 고수준 모듈은 변경할 필요가 없는 것
참고 링크1 (출처)
참고 링크2 (출처)
참고 링크3 (출처)
참고 링크4 (출처)
'CS > Java (CS)' 카테고리의 다른 글
[Java] String, StringBuffer, StringBuilder (2) | 2024.02.04 |
---|---|
[Java] 오토 박싱 & 오토 언박싱 (0) | 2023.11.07 |
[Java] 예외 처리(Exception Handling)에 관하여 (0) | 2023.02.10 |
[Java] JVM과 Garbage Collection 동작 원리 (0) | 2023.01.29 |
[Java] 자바 개념 정리 (0) | 2023.01.19 |