대부분 객체지향 / OOP에 대한 질문을 (준비 없이) 받게 되면
'객체마다 어떤 역할을 부여하고.. 다형성과.. 캡슐화를 통해.. 샬라샬라..'
이렇게 답할테지만, 좀 더 정리해보자.
객체지향의 원칙 : SOLID
좋은 객체지향이 뭐라고 생각하냐는 질문에 답하기 좋은 SOLID 원칙을 소개한다.
이 원칙을 잘 지키면 코드의 재사용성과 유지보수성을 키울 수 있다.
그리고 이 원칙을 잘 지키는 각종 디자인 패턴, 소프트웨어 개발론들이 등장하고 있으니 소프트웨어공학에서의 필수 지식이라고 할 수 있다.
단일책임원칙 Single responsibility principle
- 클래스는 단 하나의 책임을 가져야 한다.
= 클래스를 변경하는 이유가 단 한 개여야 한다. - 클래스 안에 여러 책임이 있으면
- 수정이 잦아진다.
- 심지어 수정할 경우 다른 기능에 영향이 갈 확률이 높아지기 때문에 유지 보수가 어려워 진다.
- 기능이 너무 많아 애매해서.. 재사용성도 줄어든다.
개방폐쇄 원칙 Open-closed principle
- 확장에는 개방되어있고, 수정에 있어서는 닫혀있는 구조가 되어야한다는 원칙이다.
- 새로운 조건이 추가될 때 관련된 다른 객체에 최대한 영향이 없도록 해야한다.
- 즉, 수정된 클래스 이외에 다른 클래스는 수정하지 않도록 코드를 작성해야한다.
- 그러기 위해서는 클래스간의 의존도와 결합도가 작을수록 좋다.
- 추상화와 다형성을 이용해야 한다.
- 적용 예시) 전략패턴
- 새로운 전략 Strategy 을 추가할 때(확장) 서브클래스를 생성해주면 된다.
- 이 때 Context 클래스에는 영향이 가지 않는다.(폐쇄)
리스코프 치환원칙 Liskov substitution principle
- 자식 클래스는 언제나 자신의 부모 클래스로 교체될 수 있다.
- 즉, 부모 클래스가 들어가는 자리에 자식 클래스를 넣어도 의도에 맞게 작동되야한다.
- 즉, 업캐스팅을 해도 문제가 되지 않아야한다.
- 리스코프 치환 원칙은 다형성(상속)과 관련이 깊다.
- 때문에 리스코프 치환원칙이 잘 지켜져야 개방 폐쇄원칙도 지켜질 수 있다.
인터페이스 분리의 법칙 Interface segregation principle
클라이언트 입장에서 인터페이스를 분리해야한다!
- 하나의 클래스가 인터페이스를 여러 개를 왕창 맡아서 구현하면 안된다.
- 사용하는 것만 맡아서 구현해야 한다.
- 하나의 인터페이스가 여러 기능을 왕창 갖고 있으면 안된다.
- 하나의 일반적인 인터페이스보다는 여러 개의 구체적인 인터페이스가 낫다.
- 단일책임원칙과 마찬가지로 객체가 커지는 것을 막아주는 원칙이라고 볼 수 있다.
- 객체가 커지는 것을 막아야 하는 이유는 마찬가지로 코드의 변경이 쉬워지기 때문이다.
의존관계역전법칙 Dependency inversion principle
상위 클래스는 하위 클래스에 의존하면 안된다!
- 의존 관계가 원래 구조와 역전되어, 하위 모듈이 상위 모듈에게 의존해야 한다는 원칙.
- 클래스에서 하위 클래스가 상위 클래스에 의존하는 것.
- 인터페이스에서도 마찬가지.
- 추상화와 관련이 깊다.
- 추상화(의존관계역전법칙)가 잘 지켜져야 개방 폐쇄 원칙도 잘 지켜질 수 있다.
객체지향프로그래밍 = OOP
다음으로, 그 객체지향을 어떻게 살려서 프로그래밍에 녹일지. 그걸 위해서 어떤 성질을 지원해야할지 정리해보자.
우선 객체지향 프로그래밍이란,
- 실세계의 사물을 추상화(Abstraction), 캡슐화(Encapsulation)
- 계층구조는 상속(Inheritance)
- 부모와 다른 자식의 특성, 행위는 다형성(Polymorphism)으로 구현
=> 즉, 객체의 구성으로 프로그램을 만들어 가는 것을 객체지향 프로그래밍이라고 한다.
장점
- 코드의 재사용성 증가
- 유지보수 비용 감소
구성 요소
객체
- 클래스의 인스턴스 (엄밀히는 메모리에 할당되고나야 인스턴스)
- 속성을 갖고 행위를 수행할 수 있다.
- 객체의 행위는 클래스에 정의된 행위를 공유하여 메모리를 경제적으로 사용한다.
클래스
- 같은 종류의 집단에 속하는 속성과 행위를 정의한 것.
- 객체 지향의 기본적인 user define data type
- 다른 클래스나 외부 요소와는 독립적으로 설계되어 있어야 함.
메소드
- 한 객체의 서브루틴 형태
- 객체의 속성을 조작
메시지
- 수신자와 송신자 객체들 간의 상호작용 수단
- 다른 객체에 특정 작업을 요청하는 신호를 의미
특징
다형성
- 하나의 형태가 상황에 따라 여러가지 형태를 가질 수 있는 능력.
- 오버로딩이나 오버라이딩으로 지원할 수 있다.
오버로딩
- 하나의 클래스 안에 있는 생성자, 메소드를 재정의 하는 것.
- 이름은 같지만, 매개변수의 자료형이나 개수가 반드시 달라져야 한다.
오버라이딩
- 부모 클래스의 메소드를 하위 클래스에서 재정의 하는 것.
- 상속 관계에 있는 클래스 간의 같은 이름의 메소드를 재정의
상속성
- IS-A 관계.
- ex) 부모 클래스 : 사람, 자식 클래스 : 학생, 선생님
- 학생은 사람이다. (학생 IS A 사람).
- 선생님은 사람이다. (선생님 IS A 사람).
- 위와 같은 일반화가 성립되어야 함.
- 단일 상속
- 하나의 부모만 상속받을 수 있는 것
- 다중 상속
- 여러 부모로부터 상속받을 수 있는 것
- 반복 상속
- 같은 조부모 클래스로부터 상속받은 두 부모클래스로부터 상속받는 경우
캡슐화
- 데이터를 은닉하고 데이터에 접근하는 기능을 제한적으로 운영하는 것
- 데이터 구조와 데이터를 다루는 방법을 결합시켜 묶는다고 표현할 수도 있음
- => 데이터를 기능이라는 캡슐로 보호한다.
- 접근 제한자 사용
- private : 클래스 내부에서만 접근 가능
- public : 완전 공개
- (default) : 같은 패키지에 소속된 클래스에서 접근 가능
- protected : 같은 패키지와 자식 클래스에서 접근 가능
추상화
- 공통의 속성이나 기능을 묶어 이름을 붙이는 것
추상 메소드
- 내용이 없는 메소드
- body 부분이 없고 선언만 있는 메소드
추상 클래스
- 한 개 이상의 추상 메소드를 포함하는 클래스
- 추상 클래스는 객체로 생성될 수 없다.
- 이를 상속받는 클래스가 추상메소드를 재정의하여 사용한다.
인터페이스
- 추상메소드와 상수로만 이루어져 있고, 그 외 속성은 가질 수 없음.
- 물론 최근 JDK에서는 인터페이스 안에서도 default 메소드를 정의할 수 있다.
- 자바에서 인터페이스로는 다중상속이 가능하다.
추상 클래스 VS 인터페이스 (JAVA 기준)
'취업 > 준비' 카테고리의 다른 글
Class VS Object VS Instance (0) | 2019.10.24 |
---|---|
Overriding VS Overloading (오버라이딩 VS 오버로딩) (0) | 2019.10.24 |
node.js의 특징 (0) | 2019.10.24 |
[IT면접] 그래서 동기화 문제를 어떻게 해결할건데? (2) | 2019.10.24 |
프로세스 VS 스레드 (메모리 상의 차이) (0) | 2019.10.24 |