ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Javascript 에서의 OOP !! 객체지향(+상속)을 어떻게 쓰나 보자!
    Develop/Javascript 2020. 5. 19. 02:52
    console.log('hihi');

    와우 한 번 열심히 썼었는데 절반을 썼는데 날아갔다. 엉어엉

    어떻게 썼더라.. 그래 

    이전 글에서의 OOP 내용은 Javascript의 내용은 없었다.

    efilrups.tistory.com/25?category=846222

     

    [2020.05.13] Javascript 이지만 사실 OOP 내용을 정리해보자

    console.log('hihi'); 그 동안의 정신적인 피로와 귀찮음을 드디어 물리치고 오랜만에 블로깅을 해본다. 그렇게 오랜만에 와서 하려고 하는 내용의 주제는 OOP Object Oriented Programming : 객체 지향 프로그�

    efilrups.tistory.com


    Javascript 프로토타입 기반의 프로그래밍 언어이다.

    그래서 ES6 전까지 Javascript는 prototype을 이용하여

    객체를 디자인하고 사용하였다.

    ES6 이후에는 class 키워드가 추가되면서

    class에 바로 객체를 디자인하여 사용할 수 있게 되었다.


    우선! class를 사용하지 않고 prototype을 이용하여 OOP를 구현하는 걸 살펴보자

    const Vehicle = function () {
      this.wheel = 4;
      this.frame = 'steel';  
      this.spec = function() {
        return "wheel : " + this.wheel + ", frame : " + this.frame;
      }
    }
    
    Vehicle.prototype.run = function () {
      return 'brrrrrrr!!';
    }

    Vehicle이라는 객체 생성자를 prototype을 이용해서까지 만들어보았다.

    let car = new Vehicle();
    console.log(car);
    // Vehicle {wheel: 4, frame: "steel", spec: ƒ}
    //   frame: "steel"
    //   spec: ƒ ()
    //   wheel: 4
    //   __proto__: Object

    이 객체 생성자로 car 객체를 하나 만들고 console.log로 내용을 보았다.

    여기서 __proto__라는 키워드가 있다.

    __proto__ 를 간단히 표현하면 이렇다.

    car.__proto__ === Vehicle.prototype // true

    음.. 객체 생성자의 prototype과, 만들어진 객체의 __proto__ 같은 의미이다.

    뭐랄까..  [ 자동차를 만드는 공장  /  이 자동차가 만들어진 공장 ] 이 같다. 이런 느낌..

    여기서 Vehicle을 상속하는 상황을 만들어보자.

    const Motorcycle = function () {
      Vehicle.call(this);
      this.wheel = 2;
      this.frame = 'gold';
    }
    
    Motorcycle.prototype = Object.create(Vehicle.prototype);
    Motorcycle.prototype.constructor = Motorcycle;

    오토바이 객체 생성자를 만들었다.

    Vehicle을 상속받는 과정이다. 처음에 Vehicle.call(this);에서 this를 넣어주는 이유는,

    Motorcycle에서 만들어질 객체가 Vehicle의 내용을 담고 있어야 하기 때문에

    Motorcycle로 만들어질 객체를 Vehicle까지 체이닝을 해주는 것이다.

    그리고 맨 아래 2 줄의 의미는

    Motorcycle.prototype = Object.create(Vehicle.prototype);
    // Motorcycle의 프로토타입을 Vehicle의 프로토타입의 구조를 빌려 '새롭게' 만든다. 
    
    Motorcycle.prototype.constructor = Motorcycle;
    // Vehicle의 구조를 빌려와서 '새로' 만들었기 때문에 constructor를 Motorcycle로 다시 제대로 연결해준다.

    위에 주석으로 적은 내용의 느낌을 가지고 있다. 정확하게 어떻게 표현해야 할지 모르겠다.

    자 이제 상속이 완료되었기 때문에 Motorcycle로 만든 객체에서 spec(); 과 run();을 할 수 있다.! :)

    let M = new Motorcycle();
    console.log(M);
    // Motorcycle {wheel: 2, frame: "gold", spec: ƒ}
    //  frame: "gold"
    //  spec: ƒ ()
    //  wheel: 2
    //  __proto__: Vehicle
    // Motorcycle로 만들어진 객체 안에 Vehicle에서 만든 함수 spec이 존재한다.

    그리고 __proto__: Vehicle 이 있는데, 이 의미는 이 오토바이를 만든 공장은 Vehicle 공장의 형태를 가지고 있다.  이런느낌이다.

    그렇지만 그 공장은 오토바이를 만드는 공장이지! >> 이 부분이 Motorcycle.prototype.constructor = Motorcycle; 의 느낌!

    자 다시 돌아와 원래 하고자 했던 spec과 run을 실행시켜보자.

    M.spec(); // "wheel : 2, frame : gold"
    M.run(); // "brrrrrrr!!"

    그렇다 Motorcycle에서 직접적으로 선언하고 만든 적 없는 함수인 spec과 run 함수가 실행 가능하다.

    제대로 상속이 된 것이다.!! 부모의 능력을 고대로 가져와서 잘 쓰고 있다.

    Vehicle에서 prototype을 이용하여 run을 구현했던 것처럼

    Motorcycle에서도 마찬가지로 함수, 변수 등을 prototype을 이용해서 더 추가할 수 도 있다.

    이때 추가된 것들은 Vehicle로 만들어진 객체에서는 사용할 수가 없다.


    이번엔 위의 내용들을 class 키워드를 사용하여 구현해보자.

    class Vehicle {
      constructor() {
        this.wheel = 4;
        this.frame = 'steel';  
        this.spec = function() {
          return "wheel : " + this.wheel + ", frame : " + this.frame;
        }
      }
      run () {
        return 'brrrrrrr!!';
      }
    }
    
    class Motorcycle extends Vehicle {
      constructor() {
        super();
        this.wheel = 2;
        this.frame = 'gold';
      }
    }
    

    되게 간단해졌다.  create() 어쩌고, prototype 어쩌고 constructor 어쩌고 그런 거 없이

    class라는 키워드로 간단하게 Vehicle과 Motrocycle을 구현, 상속할 수 있게 되었다.

    객체 생성 및 사용은 prototype의 방법과 같다. 

    let M = new Motorcycle();
    console.log(M);
    // Motorcycle {wheel: 2, frame: "gold", spec: ƒ}
    //  frame: "gold"
    //  spec: ƒ ()
    //  wheel: 2
    //  __proto__: Vehicle
    // Motorcycle로 만들어진 객체 안에 Vehicle에서 만든 함수 spec이 존재한다.
    M.spec(); // "wheel : 2, frame : gold"
    M.run(); // "brrrrrrr!!"

    그래서 위의 내용을 복사 붙여 넣기 했다.

    Motorcycle에서 extends Vehicle 은 Vehicle이라는 class를 상속하겠다는 의미이다.

    그리고 constructor는 '생성자'라는 의미인데,

    new 키워드로 객체가 생성될 때 해당 중괄호 안에 있는 내용을 베이스로 태어난다. 

    그 안에 super() ; 라는 것은 상속받은 class 그러니까 Vehicle를 연결해주기 위해 실행하는 부분이다.

    한 번만 써야 한다.

    내 기억에 java에서는 super라는 키워드를 this와 같은데, '부모 class의 this'의 의미로 사용했던 것 같다. 

    여하튼 여긴 javascript니까...


    휴.. 드디어 대충 정리가 끝났다.

    정리킹이지만 내 언어로, 내 말투로 정리하려니까 어렵다. 

    제기랄!!! :( 뭔가 아주 맛있는 음식을 먹고 싶지만 참고 자야겠다.

    새우리조또

    console.log('See YA! World~');

     

Designed by Tistory.