aotoyae

[JS] class 클래스, overriding 오버라이딩, 메소드 오버라이딩, 본문

JavaScript

[JS] class 클래스, overriding 오버라이딩, 메소드 오버라이딩,

aotoyae 2023. 12. 15. 00:14

 

 

: ES6에 추가된 스펙

: 이전에 비슷한 객체를 만들 때 사용했던 생성자 함수 대신 쓸 수 있다!

 

기존 생성자 함수 사용

const User = function (name, age) {
  this.name = name;
  this.age = age;
  this.showName = function () {
    console.log(this.name);
  };
};

const aoto = new User("aoto", 30);
console.log(aoto.name); // "aoto"

 

class 사용

constructor : 객체를 만들어 주는 생성자 메서드

class User2 {
  constructor(name, age) {
    this.name = name; // 객체를 초기화하는 값
    this.age = age; // 객체를 초기화하는 값
  }
  showName() { // 이렇게 클래스 내에 정의한 메서드는 User2의 프로토타입에 저장된다.
    console.log(this.name);
  }
}

const yae = new User2("yae", 40);
console.log(yae.name); // "yae"

 

 

aoto와 yae를 콘솔로 찍어보면

aoto는 showName이 user 내에 있지만

yae는 showName이 프로토타입 내에 들어가 있다.

 

하지만 실행 시 값은 잘 나온다.

console.log(aoto.showName()); // "aoto" undefined
console.log(yae.showName()); // "yae" undefined

 

그럼 class가 만들어진 이유는 뭘까?

❗️ 생성자 함수에서 new를 생략해도 Error는 뜨지 않는다.

const User = function (name) {
  this.name = name;
};

const aoto = User("aoto");
console.log(aoto); // undefined

 

❗️ 하지만 class는 Error 반환

class User2 {
  constructor(name) {
    this.name = name;
  }
}

const yae = User2("yae");
console.log(yae); // variable.js:18 Uncaught TypeError: Class constructor User2 cannot be invoked without 'new'

 

새 객체를 for in 문으로 순회했을 때

생성자 함수로 만든 객체는 그 내에 있는 프로퍼티와 프로토타입 내에 있는 프로퍼티도 반환되지만

❗️ 클래스로 만든 객체는 프로토타입 내에 있는 프로퍼티는 반환되지 않는다.

❗️ for in 문에서 제외되는 것.

const User = function (name) {
  this.name = name;
};

User.prototype.showName = function () {
  console.log(this.name);
};

const aoto = new User("aoto");
for (p in aoto) {
  console.log(p);
}
// name
// showName

class User2 {
  constructor(name) {
    this.name = name;
  }
  showName() {
    console.log(this.name);
  }
}

const yae = new User2("yae");
for (p in yae) {
  console.log(p);
}
// name

 

클래스의 상속!

생성자 함수는  상속을 할 때 프로토타입을 이용했지만,

class는 extends를 이용한다.

class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  drive() {
    console.log("drive..");
  }
  stop() {
    console.log("STOP!");
  }
}

class Bmw extends Car {
  park() {
    console.log("PARK");
  }
}

const z4 = new Bmw("blue");
console.log(z4); // Bmw {color: 'blue', wheels: 4}

이런 식으로 값이 들어가 있다.

 

 

메소드 오버라이딩 method overriding : 자식클래스가 부모클래스에 정의됐던 같은 이름의 메소드를 덮어씌우지 않고 다시 정의하는 것

Bmw 내부에 Car에서 정의한 메소드와 동일한 메소드가 있다면 어떻게 될까?

=> 덮어씌워진다!!

class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  stop() {
    console.log("STOP!");
  }
}

class Bmw extends Car {
  stop() {
    console.log("OFF"); // "OFF"
  }
}

const z4 = new Bmw("blue");
console.log(z4.stop()); // undefined

 

❗️ 부모의 메소드를 그대로 사용하면서 확장하고싶다면?

class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  stop() {
    console.log("STOP!"); // "STOP"
  }
}

class Bmw extends Car {
  stop() {
    super.stop(); // => car의 stop()을 사용하는 것
    console.log("OFF"); // "OFF"
  }
}

const z4 = new Bmw("blue");
console.log(z4.stop()); // undefined

 

오버라이딩 overriding 해보자!

class Car {
  constructor(color) {
    // class의 constructor는 빈 객채 {}로 만들어진 뒤 this로 값이 채워진다.
    this.color = color;
    this.wheels = 4;
  }
  stop() {
    console.log("STOP!"); // "STOP"
  }
}

class Bmw extends Car {
  // extends로 만든 자식객체는 빈 객체가 만들어지고 this에 할당하는 과정을 생략한다.
  constructor(color) { // (인수 추가할 때 써줘야 함, super()에도)
    super(color); // 그래서 수퍼 메소드로 부모 클래스의 constructor를 실행해줘야 한다.
    this.navigation = 1;
  }
  park() {
    console.log("PARK");
  }
}

const z4 = new Bmw("blue"); //
console.log(z4.stop()); // undefined
console.log(z4); // Bmw {color: 'blue', wheels: 4, navigation: 1}

 

❗️ 여기서 "클래스의 상속!" 아래(constructor를 따로 쓰지 않은) 함수와 달리

costructor(color){super(color);} 라고 쓴 이유는?

사실 constructor를 안 썼을 땐 아래처럼 작동되기 때문

class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  drive() {
    console.log("drive..");
  }
  stop() {
    console.log("STOP!");
  }
}

class Bmw extends Car {
  // constructor(...args){ // 이 주석 부분이 있는 것처럼 돌아간다.
  //   super(...args)
  // }
  park() {
    console.log("PARK");
  }
}

const z4 = new Bmw("blue");

 

 

 

🔗 https://youtu.be/OpvtD7ELMQo?si=v25cllbIXa1yzq2R