본문 바로가기

개념정리

9/9 [TIL] OOP(Object Oriented Programming)

컴퓨터 프로그래밍은 알고리즘 모음으로 즉, 특수한 목적을 이루기 위한 모음이다.

 

컴퓨터 언어는 개발을 도와주는 툴로써 기계 언어, 어셈블리어, 고급언어가 있으며 

 

기계 언어는 0과 1로 조합되며 컴퓨터가 알아듣는 언어이다. 0과 1로 이루어진 이진수로만으로 코딩을 하기엔 무척 어렵고 양이 엄청 방대 해 질 것이기에 어셈블리어가 등장했다고 한다

 

어셈블리어는 예로 들면 or, and? 같은 간단한 명령어들 그리고 변수도 있지만 극히 제한적이며 많은 생성을 할 수 없고 어떠한 명령어를 수행하는 함수 들을 임의로 만드는 것 또한 힘들다. 컴퓨터에 해당 명령어를 전달할 때 CPU를 통해 어셈블리어가 기계어로 바뀌게 된다.

 

고급언어는 영어로 이루어져 있고 함수를 사용하게 끔 만들어 놓은 것이라고 보면 된다. 인터프리터로 컴파일을 하지 않고 javascript 처럼 라인별로 컴퓨터에서 가동될 수 있도록 변환한다.

 

기계 언어 -> 어셈블리어 -> 고급언어 순으로

여러 가지 환경에서 사용 가능하며 호환이 가능하고 작성하기 쉬워지는 것과 유연함을 가지게 되고

 

고급언어 -> 어셈블리어 -> 기계 언어 순으로

빠르고 코드의 압축(코드의 양을 말하는 건 아님)이 된다고 생각하면 된다. 

 

이러한 고급언어들은 절차지향적 언어와 객체지향적 언어로 구분하여 볼 수 있다.

 

먼저 절차지향적 언어는 물이 위에서 아래로 흐르는 것처럼 순차적인 처리가 주가 되며 프로그램 전체가 유기적으로 연결되도록 만드는 프로그래밍 언어다. 예를 들면 C, COBOL, Fortran, LISP, HTML, VBScript 가 존재한다.

 

[OOP(Object-Oriented Programming)란?]

객체지향적 언어는 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, "객체" 들의 모임으로 파악하고자 하는 것이다. 객체들의 모임으로 파악함으로써 재사용이 가능하며 이는 클래스란 프로토타입이라고 볼 수 있고 클래스(청사진)에 세부사항을 넣으면(컨스트럭터에서 정의해줌) 객체로 만들어진다고 보면 된다.

예를 들면 java script, java, C++, C#, 파이썬, PHP, Ruby, Perl, Object Pascal, Objective – C, Dart, Swift, Scala, Common Lisp 등이 있다.

출처 : https://www.fun-coding.org/00_Images/oop2.png

클래스(이름) class Car

속    성(특성) color; price; speed;

함    수(행동) Start(); Backward(); Forward(); Stop();

 

OOP(Object Oriented Programming)의 특징에는 4가지가 존재하는데

 

첫째, 캡슐화 로써 말 그대로 안에 넣어 놓는다고 이해하면 편할 것 같다. 속성, 기능들을 객체에 넣어서 사용하며 이는 복잡도를 줄여주며 재사용성을 늘려준다는 이점을 가진다. 만약을 캡슐화를 진행하지 않는다면 우리가 취급하고자 하는 데이터가 많을 때에 시간이 오래 걸리게 되는 단점이 생긴다.

 

두 번째, 상속화 는 부모의 특징을 물려받는다(?)라는 뜻으로 이해하면 될 것 같다. 우리가 DOM에서도 배웠던 것처럼 HTMLDivElement(자식)는 HTMLElement(부모)의 기능과 속성을 상속받는다.라는

 

세 번째, 추상화는 쉽게 말하면 속은 복잡하게 막 구현이 되어 있는데 사용자가 쓰기엔 가장 간단한 것으로 우리가 계산기를 쓸 때는 1+1= 버튼만 눌러줘도 답이 표시되지만 계산기 저 뒤편에는 어떤 명령어들이 작동하는지를 우리가 일일이 알 필요는 없다는 뜻이다. 복잡한 부분은 사용자가 알 필요가 없으며 이는 인터페이스가 간단해지는 것에 일조를 하고 사용자가 건드릴 부분도 최소화가 될뿐더러 이는 복잡도를 줄여주게 된다.

 

마지막 네 번째, 여러 가지의 형태(다형성) 은 하나의 객체를 여러 개의 타입으로, 하나의 타입으로 여러 종류의 객체를 여러 가지 모습으로 해석될 수 있는 성격이라고 생각하면 된다. 쉽게 말하면 하나의 객체를 여러 가지 타입으로 선언할 수 있다는 뜻으로 봐도 되며 이는 일일이 함수를 정의를 하나하나 해줄 필요 없이 부모에게 정의해준 다음 상속을 받아서 진행할 수도 있고 이는 훨씬 유연하고 클린 한 코딩을 할 수 있게 해 준다.

 

이를 바탕으로 객체지향이라는 것은 사람이 세계를 보고 이해하는 방법을 흉내 낸 방법론이라고 생각하면 될 것이다.

 

 

[JavaScript에서 Object를 생성하는 여러 가지 방법들]

1 ) Functional Instantiaiton : 함수를 이용해서 인스턴스 객체 생성

1
2
3
4
5
6
7
8
var Car = function() {
  var someInstance = {};
  someInstance.position = 0;
  someInstance.move = function() {
    this.position += 1// this === someInstance
  }
  return someInstance; // 인스턴스 반환
 };
cs

1. 함수 생성 : 함수 이름은 대문자로 시작(일반 함수와 구분하기 위함)

2. 빈 객체 생성 : 함수를 이용해 만든 객체(인스턴스)

3. 빈 객체에 프로퍼티 및 메서드 추가

4. 빈 객체 반환 : 인스턴스 반환

 

단점 : 함수 안에 메서드가 정의되어 있기 때문에 인스턴스(객체)를 생성할 때마다, 인스턴스에게 메서드를 할당하므로 인스턴스 메서드의 개수만큼 컴퓨터 메모리를 차지한다. 그래서 메모리 낭비가 심하다.

 

 

2 ) Functional Shared Instantiaiton : Functional 방법의 단점을 보완할 수 있다. 바로 인스턴스의 메서드를 함수 밖에서 정의 및 할당한다. 그리고 인스턴스의 메서드를 공유하기 위해서 따로 외부 함수 extend를 만든다. 그러면 메서드의 메모리 주소만을 참조해서 메모리 효율에 좋다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var extend = function(to, from) {
  for(var key in from) {
    to[key] = from[key];
  }
};
 
 
var someMethods = {}; // 함수 Car 외부에 인스턴스에게 공유할 메서드 정의 및 할당
someMethod.move = function() {
  this.position += 1// 함수 extend 통해 this === someInstance
};
 
 
var Car = function() {
  var someInstance = {};
  someInstance.position = 0;
  someInstance.move = function() {
    this.position += 1// this === someInstance
  }
  return someInstance; // 인스턴스 반환
 };
 
 var car1 = Car(5);
cs

1. 함수 생성 : 함수 이름은 대문자로 시작(일반 함수와 구분하기 위함)

2. 함수 안에 빈 객체 생성 : 인스턴스

3. 빈 객체에 프로퍼티만 추가 : 빈 객체 안에서 프로퍼티 추가도 가능(결국 같음)

4. 함수 밖에 메서드 추가 : 인스턴스의 메서드 

5. 함수 안의 인스턴스(프로퍼티만 있는)와 함수 밖의 메서드 연결하기 : 외부 함수 extend 만들기

5 - 1.  외부 함수 extend의 첫 번째 인자는 인스턴스 객체, 두 번째 인자는 메서드 객체

5 - 2.  for... in 이용하여 메서드 객체 있는 key와 value를 인스턴스 객체에 추가.

6.  빈 객체 반환 : 인스턴스 객체

 

장점 : 메서드 객체의 주소 값이 인스턴스 객체와 연결되어 있다. 메모리 효율에 좋다.

단점 : 메서드 객체 수정하고 인스턴스 객체를 생성하면 기존의 인스턴스의 메서드 객체의 주소와 수정한 인스턴스의 메서드 객체의 주소는 다르다. 

 

 

3 ) Prototypal Instantiation : 프로토타입 체인을 이용하여 인스턴스 객체 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var someMethods = {};
someMethod.move = function() {
  this.position += 1;
};
 
 
var Car = function() {
  var someInstance = Object.create(someMethods)
  someInstance.position = 0;
  someInstance.move = function() {
    this.position += 1// this === someInstance
  }
  return someInstance; // 인스턴스 반환
 };
 
 var car1 = Car(5);
cs

Object.create() 메서드를 이용해서 인스턴스 객체의 부모 객체에 메서드 정의 및 할당한다.

즉, 지정된 프로토타입 객체 및 속성(property)을 갖는 새 객체를 만든다.

1. 함수 생성 : 함수 이름은 대문자로 시작(일반 함수와 구분하기 위함)

2. 인스턴스 객체 정의 하기 : Object.create() 메서드를 이용해서 메서드 객체를 할당하는 객체 생성.

3. Functional Shared Instantiation처럼 인스턴스의 메서드는 함수 밖에서 정의 및 할당/ 프로퍼티는 함수 안에서 추가

4. 인스턴스 객체 반환

 

var obj1 = Object.create(Object.prototype);

 

즉, 객체 obj1은 Object의 부모 객체를 상속받는다. 프토토타입의 참조가 주목적이다.

 

장점 :  부모 객체에 메서드를 정의하면 인스턴스의 메서드를 복사 없이 모든 객체의 메서드 접근 가능하다.

단점 :  인스턴스의 메서드를 사용하기 위해서 인스턴스를 만들어야 하고, 함수에서 인스턴스 객체를 반환해야 한다.

 

 

4 ) Pesudoclassical Instantiation : 인스턴스 객체 생성 시, new 키워드 사용하며, this를 사용한다.

함수는 그냥 인스턴스 객체를 만들기 위한 틀이라고 생각하자! 함수 생성 시, 프로토타입 객체도 동시에 생성된다.

1
2
3
4
5
6
7
8
var Car = function(position) {
  this.position = position;
};
Car.prototype.move = function() {
  this.position += 1;
};
 
var car1 = new Car(5);
cs

메소드를 프로토 타입으로 만들며 찍어 낼 때 new operator를 붙여야 한다.

 

1. 함수 생성 : 함수 이름은 대문자로 시작(일반 함수와 구분하기 위함)

2. 빈 객체 생성 X : this를 이용해서 함수 안에서 프로퍼티 추가

3. 메서드 추가 : 부모 객체에 바로 메서드를 추가

4. 인스턴스 객체 반환 X

 

장점 : 인스턴스 객체를 생성하는데 최적화되어 있다. 함수에서 인스턴스 객체 반환할 필요가 없다.

 

 

[JavaScript에서 Prototype은 무엇이고 왜 사용해야 하나?]

  • 자바스크립트는 객체지향 언어이지만 객체지향 언어에서 중요한 클래스(Class)라는 개념이 없음
  • 대신 프로토타입(Prototype)이라는 것이 존재하는데, 이를 이용하여 클래스가 하는 역할인 상속을 흉내 내도록 구현해 사용함
  • 자바스크립트에서는 함수와 new를 활용해 클래스를 비슷하게 흉내 냄

'개념정리' 카테고리의 다른 글

9/21[TIL]Async & Await  (0) 2020.09.21
9/9 [TIL] Inheritance Patterns  (0) 2020.09.09
9/7[TIL]Graph, Tree, BST  (0) 2020.09.08
9/4[TIL]Linked List, Hash Table  (0) 2020.09.07
9/3[TIL] Stack & Queue  (0) 2020.09.04