만약 우리가 브라우저에 다양한 도형을 그릴 수 있는 웹 어플리케이션을 만든다고 가정해보자.
도형을 만들 때 필수적인 것들, 예를 들어 너비/높이/색상 등.. 공통적으로 쓰이는 속성 값을 한번에 정의 한 다음, 재사용
하면 더욱 간편할 것이다.
class Shape {
constructor(width, height, color) {
this.width = width;
this.height = height;
this.color = color;
}
draw() {
console.log(`drawing ${this.color} color of`);
}
getArea() {
return this.width * this.height;
}
}
// 만약 Rectangle 이라는 클래스를 만들고 싶다면, 계속 반복해서 하기 보다는
// extends 라는 키워드를 이용해서 Shape 을 연장한다.
class Rectangle extends Shape {}
class Triangle extends Shape {}
const rectangle = new Rectangle(20, 20, 'blue');
rectangle.draw(); // drawing blue color of
const triangle = new Triangle(20, 20, 'red');
triangle.draw(); // drawing red color of
이렇게 상속을 이용하게 되면 공통되어지는 것들을 일일히 작성하지 않아도 상속(extends)을 통해 동일한 것들을 계속 재사용 할 수 있다.
const rectangle = new Rectangle(20, 20, 'blue');
rectangle.draw(); // drawing blue color of
console.log(rectangle.getArea()); // 400
const triangle = new Triangle(20, 20, 'red');
triangle.draw(); // drawing red color of
console.log(triangle.getArea()); // 400
하지만 삼각형의 면적을 구할 때는 (width * height) /2
를 해야 한다. 여기서 다양성이 빛을 발휘한다. 우리가 필요한 함수만 재정의 해서 사용할 수 있다
! 이것을 오버라이딩
이라고 한다.
class Triangle extends Shape {
draw() {
console.log('🔺');
}
getArea() {
return (this.width * this.height) /2 ;
}
}
const triangle = new Triangle(20, 20, 'red');
triangle.draw(); // 🔺
console.log(triangle.getArea()); // 200
이렇게 필요한 함수들만 오버라이딩 해서 작성할 수 있다. 그런데 만약 공통적으로 정의한 draw()
도 그려주면서, 조금 더 색다르게 더 그려주고 싶을 경우가 있을 것이다.
그럴 경우에는,
class Triangle extends Shape {
draw() {
super.draw();
// 부모의 draw 를 호출하게 되면 부모의 메소드도 호출 되고
// 이어서 우리가 정의한 draw 메소드도 함께 호출 되는 것을 볼 수 있다.
console.log('🔺');
}
}
const triangle = new Triangle(20, 20, 'red');
triangle.draw();
// drawing red color of
//🔺
이렇게 super
를 활용하여 원하는 결과물을 출력할 수 있다.