#3 OOP(Object-Oriented Programming)

0_23·2022년 12월 22일
1

[Nomard Corders][OOP]

목록 보기
3/3
post-thumbnail

이번 포스트에서는 OOP(객체지향 프로그래밍)의 4가지 핵심 개념에 대해서 TypeScript로 설명하려고 한다.
4가지 핵심 개념은 다음과 같다.
1. Encapsulation(캡슐화)
2. Inheritance(상속)
3. Abstraction(추상화)
4. Polymorphism(다형성)

먼저 Encapsulation부터 알아가보자.

1. Encapsulation(캡슐화)

Encapsulation은 데이터 그리고 데이터를 활용하는 함수를 캡슐 혹은 컨테이너 안에 두는 것을 의미한다. 이 경우, 캡슐은 class를 의미한다고 볼 수 있다.

예를 들어보도록 하겠다.

이 코드를 보면 Elon Musk라는 객체가 있는 데이터가 있다. 또한 그의 자산을 계산하는 함수가 있는데 그가 갖고 있는 주식에 주가를 곱해서 계산을 하는 기능을 한다.

함수 그리고 데이터가 개념적으로 연관되어 있기때문에 캡슐화를 사용해서 코드를 개선할 수 있다. 다음 코드와 같이 데이터와 함수를 클래스 안에 넣는 것을 뜻한다.

위 코드의 장점은 'this' 키워드를 사용해서 데이터에 직접 액세스할 수 있어서 코드가 좀 더 구조화되었고, 함수나 메소드가 인수를 취할 필요도 없어졌다. 또한, 캡슐화를 사용하여 표시할 클래스의 속성과 숨길 속성을 선택할 수 있다.

이 경우, 모든 필드 또는 클래스가 'private'이기 때문에 해당 클래스 외부의 사용자는 해당 필드에 액세스하거나 수정할 수 없다. 이러한 이유로 다음 코드과 같은 작동하지 않는다.

캡슐화는 어떻게 클래스 정보에 접근 혹은 수정하는지를 졀정하는 권한을 제공한다. 예를 들어, 'Entrepreneur'에서 'name'을 공개하고자 하는 경우 다음 코드의 'getName' 메소드같이 만들 수 있다.

데이터 그리고 class안에 있는 해당 데이터를 이용하는 함수를 잘 정리하는 방법론으로 설명할 수 있다. 이 덕분에 원하는 데이터을 표시하거나 숨길지를 선택할 수 있다.
이상 캡슐화에 대한 설명이었다.

2. Inheritance(상속)

이번에는 상속에 대해 살펴보도록 하자.

상속 덕분에 코드를 더 작은 단위로 class로 쪼개고, 재사용 할 수 있다.

이번 에도 예를 들어보도록 하겠다.

'Entrepreneur'클래스 외에 'Actor' 클래스를 갖고 싶다면, 'Actor' 클래스는 'Entrepreneur'클래스 처럼 'firstName' 그리고 'lastName'을 갖고 있어야 한다. '상속'이 없다면 중복된 'firstName' 및 'lastName' 속성을 가진 두 개의 별도 클래스를 만들어야 한다. 이 방법은 그닥 좋지 않다. 그럼 위 코드에서 '상속'을 활용하면 어떻게 되는지 살펴보자.

먼저 'Actor' 그리고 'Entrepreneur' 클래스 둘 다 'firstName' 및 'lastName' 속성이 필요하다. 이 두개의 'firstName' 및 'lastName' 속성을 다음과 같이 'Person'이라는 다른 클래스로 이동시킬 수 있다.

그리고 'Actor' 그리고 'Entrepreneur' 클래스가 'Person' 클래스의 'firstName' 및 'lastName' 속성을 '상속' 하는 거다. TypeScript의 경우 이 부분에 'extends(확장)' 키워드를 다음과 같이 쓰면 된다. (클래스를 '확장'하는 구문은 언거간 변경되지만, 핵심 개념은 동일하다.)

클래스를 'extend'하면 'child' 클래스는 'parent' 클래스의 모든 속성과 메소드를 '상속' 혹은 수신하게 된다. 즉 'Actor' 클래스 그리고 'Entrepreneur' 클래스 둘 다 'firstName' 및 'lastName' 속성을 갖게 되는 것이다. 또한 'sayHi' 메소드를 'Person' 클래스에서 실행하면, 다음과 같이 'Actor'클래스와 'Entrepreneur' 클래스 둘 다 'sayHi' 메소드를 사용할 수 있다.

'상속'은 'devide(분할)' 및 'conquer(정복)'을 가능하게 한다. 클래스들을 일단 작게 쪼개고, 분할한 후에 레고 처럼 클래스 들을 구성할 수 있는 것이다.
이상 상속에 대한 설명이었다.

3. Abstraction(추상화)

자 이제 추상화에 대해 알아보자. C++의 창시자인 'Bjarne Stroustrup'는 추상화를 다음과 같이 정의했다.

구현 세부 정보를 숨기는 일반 인터페이스를 지정하는 행위

운전을 예로 들어보겠다. 차량을 운전할 때, 이를 위한 'interface' 즉, 스티어링 휠, 페달, 각종 버튼들 등 이것들은 차량 제조사에 의하여 노출이 되어있다. 우리는 해당 인터페이스만 활용해서, 차량을 조종할 수 있다. 하지만 구현 세부 정보는 노출되어 있진 않다. 따라서 운전자는 브레이크나 엔지 어떻게 작동하는지 세부 사항을 알지 못한 채 운전할 수 있다. 여기서 세부 정보는 모두 숨겨져있는 것이다.

또다른 예를 들면서 '추상화'에 대해 알아보자. 예를 들어 'JavaScript'에서의 배열이 맘에 들지 않다고 하자. 그래서 그 위에 우리의 배열 '추상화'를 구축할 것이다. 이를 위해 'BetterArray'라는 클래스를 만들도록 하자. 'BetterArray' 내부에는 배열이 있다. 그러나 배열을 노출하는 대신 더 편하게 조종할 수 있는 노출된 'interface'를 만들어 보겠다.

이 클래스는 배열 내부의 항목을 가져오거나 추가, 제거, 수정하는 메소드가 있다. 그래서 누군가가 'BetterArray'를 사용하게 되면, 우리가 노출한 'interface'를 사용하여 배열과 상호 작용할 수 있다. 다음과 같이 '추상화'를 만들어봤다.

위 코드는 'BetterArray'의 일반 인터페이스를 세부 실현 정보들은 숨긴채 정의했다. 추상화를 사용하는 다른 큰 장점은 만약 더 빠른 속도를 위해 '수정'의 내부 작업을 바꾼마면 '수정' 메소드를 사용하는 그 누구도, 뭔가를 바꿀 필요가 없다. 다음코드 처럼 구현 세부 내용이 바꾸려고 해도 인터페이스는 그대로 유지되어있기 때문이다.

이상 추상화에 대한 설명이었다.

4. Polymorphism(다형성)

이제 마지막 파트인 Polymorphism(다형성)에 대해 알아보자. 'Poli'는 'Polygon(다각형'처럼 '여럿'을 뜻한다.

그리고 'morphos'는 'Amorphous(무정형)' 혹은 'morphology'형태학'처럼 '형태', '모양'을 뜻한다.

따라서 Polymorphism은 여러개의 + 형태 다형성이라는 뜻이된다. OOP에서의 다형성을 이해하기 위해서는 '상속'에서 부모 클래스의 속성이 자식 클래스에게 상속되는 것을 기억해야한다.

다음 코드를 예시로 들어보자.

'한국인'이나 'Italian' 클래스는 둘다 'Person' 클래스에 확장됨을 알 수 있다. 즉 '한국인' 그리고 'Italian'클래스의 객체 모두는 sayHi 메소드를 갖게된다. 그러나 '한국인' 클래스가 'Person' 클래스에서 확장이 되었지만, 'Italian'과 sayHi 방법을 다르게 하기를 원할 때 여기서 다형성이 등장하게 된다. 이를 위해선 '한국인' 클래스만의 sayHi 메소드를 재정의 해야한다.

이것을 method overriding(메소드 오버라이딩)이라고 한다.sayHi라는 같은 이름을 쓰지만, 다른 구현 방식인 것이다. 이후로 sayHi 메서드를 '한국인' 클래스에서 호출하면 'Italian' 클래스와 다른 방식인 "안녕"이라는 인사를 하게 된다.
이뿐아니라 다형성에서는 '한국인' 클래스의 sayHi 메서드는 'Person' 클래스의 결과값과 같아야한다. 'Person' 클래스에서 String으로 반환하기 때문에 'Person' 클래스 에서 확장된 '한국인' 클래스는 sayHi 메서드를 오버라이딩 하는데 같은 데이터 타입인 String을 반환해야한다. String 대신 다른 데이터 타입으로 반환하려고 한다면, '한국인' 클래스의 'sayHi' 메서드에서 TypeScript는 이를 막고 에러를 표기할 것이다. sayHi 메소드는 String을 반환해야하기 때문이다. 이것이 OOP에서의 다형성이다.

보다시피 부모 클래스에서의 메소드를 오버라이딩 할 수 있는데, 그럼에도 메소드가 어떻게 작동해야하는지 규칙이 정해져 있다.

덕분에 클래스의 핵심은 그대로 있고, 구현 방식의 모양과 모습은 달라지게 되는 것이다. 다형성을 이용하면 '한국인' 클래스와 'Italian' 클래스가 같은 sayHi 메서드를 호출하지만 각기 다른 String으로 반환할 것임을 알 수 있다.

이상 캡슐화, 상속, 추상화, 다형성까지 OOP의 핵심 개념 4가지를 설명해보는 포스트였다.

0개의 댓글