[자바스크립트] 클래스 상속
[자바스크립트] Class 개념과 기본 문법
클래스 (Class) 자바스크립트의 클래스 문법은 ES6에서 추가된 것으로 좀 더 JAVA와 비슷하게 객체 지향을 표현하기 위해 추가된 것이다. ES5까지는 클래스가 없었기 때문에 프로토타입 체이닝을 통
codingralro.tistory.com
저번 포스팅에서는 자바스크립트 클래스의 개념과 기본 문법에 대해서 다루었다. 이번 시간에서는 클래스의 주요 개념 중 하나인 상속에 대해서 알아보겠다.
클래스 상속
클래스의 상속이란, 클래스의 기능을 다른 클래스도 사용할 수 있게 해주는 것이다. 자바스크립트에서 클래스를 상속하기 위해서는 extends 키워드를 사용하여 상속한다.
// 클래스 상속
// extends
class Parent {
// ...
}
class Child extends Parent {
// ...
}
위의 예제는 Child 클래스가 Parent 클래스를 extends 키워드를 통해 상속 받는 코드이다. 이런 관계를 상속 관계라고 하기도 하고 부모-자식 관계, 슈퍼-서브 관계 등 여러가지로 불린다.
이렇게 extends 키워드를 통해 다른 클래스를 상속 받게 되면, 여러 가지 일들이 가능해진다.
- 자식 클래스를 통해 부모 클래스의 정적 메소드와 정적 속성을 사용할 수 있다.
- 부모 클래스의 인스턴스 메소드와 인스턴스 속성을 자식 클래스의 인스턴스에서 사용할 수 있다.
즉, 자식 클래스는 부모 클래스의 기능들을 정적이든 아니든 물려받아 사용하는 것이 가능하다.
class Parent {
static parentStaticVal = 'static parent';
static parentStaticMethod() {
console.log(`I'm static parent`);
}
parentVal = 'parent';
parentMethod() {
console.log(`I'm parent`);
}
}
class Child extends Parent {};
//static 사용 가능
console.log(Child.parentStaticVal); //static parent
Child.parentStaticMethod(); //I'm static parent
//일반 프로퍼티도 사용 가능
const child = new Child();
console.log(child.parentVal); //parent
child.parentMethod(); //I'm parent
super
super는 자바에서와 마찬가지로 클래스가 상속 받은 부모 클래스를 가리킨다. super는 어디에서 사용하냐에 따라 부모 클래스의 무엇에 접근하는지가 달라진다.
- 생성자 내부에서 super를 함수처럼 호출하면, 부모 클래스의 생성자가 호출
- 정적 메소드 내부에서는 super.prop과 같이 써서 부모 클래스의 정적 속성에 접근
- 인스턴스 메소드 내부에서는 super.prop과 같이 써서 부모 클래스의 인스턴스 속성에 접근
class Parent {
constructor(name, age) {
this.name = name;
this.age = age;
}
static printInfo(parent) {
console.log(parent.name + " " + parent.age)
}
printInfo() {
console.log(this.name + " " + this.age)
}
}
class Child extends Parent {
constructor(name, age) {
super(name, age) // => parent의 constructor를 호출
}
static printInfo(child) {
super.printInfo(child) //=> Parent의 정적 메소드를 호출
console.log(`I'm child`)
}
printInfo() {
super.printInfo(); // => Parent의 instance 메소드를 호출
console.log(`I'm child`)
}
}
const child = new Child('kim', 26)
Child.printInfo(child); //kim 26 \n I'm child
child.printInfo(); //kim 26 \n I'm child
super 키워드를 통한 부모 클래스의 메소드 호출은 자식 클래스에서 오버로딩을 할 때, 부모 클래스의 메소드에서 내용을 변경없이 추가하기만 할 경우에, 코드를 중복 작성하지 않고도 구현할 수 있다는 장점이 있다.
Private 클래스 변수 생성
자바스크립트에서 클래스의 프로퍼티는 static 또는 public 이였다. 그래서 반쪽짜리 클래스 구현체로 비난을 받기도 하였찌만 ES2021부터는 메소드와 필드명 앞에 #을 붙여서 private 메서드와 필드 정의가 가능해짐으로 좀 더 자바의 클래스에 가까워졌다.
class myPrivate {
// private 변수 생성
#language = 'javascript'
// private 메소드 생성
#privatePrint() {
console.log(this.#language) //private 변수 호출
}
publicPrint() { //내부에서는 private 필드에 접근 가능
this.#privatePrint();
}
}
const myP = new myPrivate();
// myP.privatePrint() => private은 외부에서는 접근 할 수 없음X
myP.publicPrint(); //javascript
private 변수와 메소드는 #을 통해 선언하기 때문에, 해당 변수와 메소드를 클래스 내에서 접근할 때에도 #을 붙여서 접근해야 한다. 또한 private 메소드는 클래스 외부에서는 접근할 수 없다.
private fields 체크
클래스를 사용하다 보면, 해당 변수가 private인지 public 인지 확인이 어려운 경우가 생긴다. 이 때, 해당 클래스가 private 프로퍼티를 가지고 있는 지 확인하고 싶으면 in 키워드를 사용하여 확인 할 수 있다.
class myPrivate {
// private 변수 생성
#language = 'javascript'
// private 메소드 생성
static hasLanguage(obj) {
return #language in obj;
}
}
const myP = new myPrivate();
// myP.privatePrint() => private은 외부에서는 접근 할 수 없음X
console.log(myPrivate.hasLanguage(myP)); //true