본문 바로가기
시작/TIL(Today I Learned)

230109 - JavaScript - class 클래스와 상속

by 백씨네 2023. 1. 9.

오늘 내가 배운 것

1. 클래스

2. 클래스 상속

3. 메서드 오버라이딩

4. 생성자 오버라이딩

 

클래스

객체지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메서드를 정의하는 틀
객체를 정의하기 위한 상태와 메서드로 구성된다.
동일한 종류의 객체를 여러 개 생성해야 하는 경우가 많은데 class 문법을 이용하면 객체지향 프로그래밍에서 사용되는 다양한 기능을 자바스크립트에서 사용할 수 있다.

 

기본 문법

class MyClass {
    constructor(){}
    method1(){}
    method2(){}
    method3(){}
    ...
}


//객체 생성
const a = new MyClass()
console.dir(a)

사진 1

 

생성자 메서드 constructor()는 객체의 기본상태를 설정해 주고, new에 의해 자동으로 호출되므로, 특별한 절차 없이 객체를 초기화할 수 있다.

 

class 예시

class User{
    constructor(name){
        this.name = name
    }
    sayHi(){
        alert(this.name)
    }
}

//사용법:
let user = new User("John")
user.sayHi()


console.log(typeof User)//function

사진 2

 

자바스크립트에서의 클래스는 함수의 한 종류이다.

사진 3

 

 

class User{} 문법구조가 하는 일은


- User라는 이름을 가진 함수를 만들고, 함수 본문은 constructor메서드 안에서 가져온다. 생성자 메서드가 없으면 본문이 비워진 채로 함수가 만들어진다.
- sayHi 같은 클래스 내에서 정의한 메서드를 User.prototype에 저장한다.

new User를 호출해서 객체를 만들고 객체 안에 있는 메서드를 호출하면 메서드를 prototype안에 메서드를 찾아 메서드를 실행한다.

 

사진 1번을 참고하면 이해하기 쉽다.

 

 

클래스 표현식

클래스를 변수에 할당하여 사용할 경우 이 이름은 클래스 내부에서만 사용할 수 있다.

let User = class MyClass{
    sayHi(){
        alert(MyClass);
    }
}
new User().sayHi() // MyClass의 정의가 나옴
alert(MyClass) // error 발생

 

 

 

클래스 상속

클래스 상속을 사용하면 클래스를 다른 클래스로 확장할 수 있다.
기존에 존재하던 기능을 베이스로 하고 새로운 기능을 추가로 넣을 수 있다.

 

 

extends

//기본 문법

class Child extends Parent {}

extends를 이용하여 클래스를 확장할 수 있다.

class Animal {
    constructor(name){
        this.speed = 0
        this.name = name
    }

    run(speed) {
        this.speed = speed
        console.log(`${this.name}은 속도 ${this.speed}로 달립니다.`)
    }
    stop(){
        this.speed = 0;
        console.log(`${this.name}이 멈췄습니다.`)
    }
}

let Animal = new Animal("동물")

 

class Rabbit extends Animal {
    hide(){
        console.log(`${this.name}가 숨었습니다.`)
    }
}

let rabbit = new Rabbit("흰 토끼")
rabbit.run(5) //흰토끼 은 속도 5로 달립니다.
rabbit.hide() // 흰토끼가 숨었습니다.

 

클래스 Rabbit으로 만든 객체는 Rabbit의 매서드도 사용할 수 있고, Animal의 매서드도 사용할 수 있다.
extends는 Rabbit.prototype.[[Prototype]]을 Animal.prototype으로 설정한다.
그렇기 때문에, Rabbit.prototype에서 메서드를 찾지 못하면, Animal.prototype에서 메서드를 찾아서 사용한다.

 

 

 

메서드 오버라이딩

//위에 코드와 같이 봐주세요

class Rabbit extends Animal {
    stop()
}

class Rabbit에 class Animal이 상속되어서 run(), stop()가 상속되어 있는데, Rabbit에서 stop()을 다시 정의하게 되면 기존에 상속받았던 stop()이 아닌 Rabbit에 정의된 stop()을 사용한다.

 

class Rabbit extends Animal {
  hide() {
    console.log(`${this.name}가 숨었습니다!`)
  }

  stop() {
    super.stop() // 부모 클래스의 stop을 호출해 멈추고,
    this.hide() // 숨는다.
  }
}

 

상속을 받아서 사용하기 위해서는 super()를 사용하여 상속받는다.

 

 

생성자 오버라이딩

class Animal {
  constructor(name) {
    this.speed = 0;
    this.name = name;
  }
}

class Rabbit extends Animal {

  constructor(name, earLength) {
    this.speed = 0;
    this.name = name;
    this.earLength = earLength;
  }
}

// error
let rabbit = new Rabbit("흰 토끼", 10);

 

상속 클래스의 생성자는 반드시 super()을 호출해야 한다. this를 사용하기 전에 호출한 상태로 사용하여야 한다.

일반 클래스가 new를 이용하여 실행하게 되면, 빈 객체가 만들어지고 this에 빈 객체를 할당한다. 하지만 상속 클래스의 생성자 함수가 실행이 되면, 빈 객체를 만들고 this에 이 객체를 할당하는 일을 부모 클래스의 생성자가 처리하길 기다린다.

 그래서 super를 호출하여 부모 생성자를 실행해 주어야 한다. 실행을 해주지 않게 되면 this가 될 객체가 만들어지지 않기 때문에 에러를 발생한다.

 

 class Animal {
  constructor(name) {
    this.speed = 0;
    this.name = name;
  }
}

class Rabbit extends Animal {
  constructor(name, earLength) {
    super(name);
    this.earLength = earLength;
  }
}

반드시 super()를 이용하여 상속받아 사용한다.

 

 


참고 : https://ko.javascript.info/

댓글