- '클래스' 란? : 객체를 생성하기 위한 일종의 템플릿!
- 책상을 만들기 위한 설계도
- LIKE 붕어빵을 만들기 위한 붕어빵 틀
- '인스턴스' 란? : 클래스를 통해 만들어진 실제 객채들!
- 설계도를 보고 만들어진 실제 책상
- LIKE 붕어빵 틀로 만들어진 붕어빵들 🥐
class Person {
// 생성자
constructor(name, age) {
// new라는 키워드를 이용해서 인스턴스를 만들 때, 기본적으로 넣어야 하는 값들을 의미해요! :)
// 여기서 말하는 this는 (미래에 생성할) 인스턴스를 의미한다!
this.name = name;
this.age = age;
}
// 다양한 메소드를 아래와 같이 정의할 수 있어요.
// 여기서 this.name으로 내부 값을 접근해야 한다!
sayHello() {
console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
}
}
const person1 = new Person("Alice", 30);
const person2 = new Person("Bob", 25);
// 만든 객체를 토대로 메서드 호출해보기
person1.sayHello(); // "Hello, my name is Alice and I am 30 years old."
person2.sayHello(); // "Hello, my name is Bob and I am 25 years old."
class
라는 키워드를 사용한다.constructor
는 클래스의 생성자 함수이다. 생성자 함수는 객체를 생성할 때 호출되며, 객체를 초기화하는 역할을 한다.getter
는 속성 값을 반환하는 메서드.setter
는 속성 값을 설정하는 메서드. (입력값에 대한 유효성 검사 시 주로 사용)class Rectangle {
constructor(height, width) {
// underscore : private(은밀하고, 감춰야 할 때)
// this로 접근하는 property에 underscore(_)를 사용하자.
this._height = height;
this._width = width;
}
// width를 위한 getter
get width() {
return this._width;
}
// width를 위한 setter
set width(value) {
// 검증 1 : value가 음수이면 오류!
if (value <= 0) {
console.log("[오류] 가로길이는 0보다 커야 합니다!");
return;
} else if (typeof value !== "number") {
console.log("[오류] 가로길이로 입력된 값이 숫자타입이 아닙니다!");
return;
}
this._width = value;
}
// height를 위한 getter
get height() {
return this._height;
}
// height를 위한 setter
// understore(_)![](https://velog.velcdn.com/images/hw1635/post/85e58570-3f6e-40e0-9931-6f8c8172c06c/image.png)
를 쓰지 않으면 무한루프에 빠져서 콜스택이 꽉차게 된다!
set height(value) {
// 검증 1 : value가 음수이면 오류!
if (value <= 0) {
console.log("[오류] 세로길이는 0보다 커야 합니다!");
return;
} else if (typeof value !== "number") {
console.log("[오류] 세로길이로 입력된 값이 숫자타입이 아닙니다!");
return;
}
this._height = value;
}
// getArea : 가로 * 세로 => 넓이
getArea() {
const area = this._width * this._height;
console.log(`넓이는 => ${area}입니다.`);
}
}
// instance 생성
const rect1 = new Rectangle(10, 7);
rect1.getArea(); // 넓이는 => 70입니다.
const rect2 = new Rectangle(10, 30);
rect2.getArea(); // 넓이는 => 300입니다.
this
로 접근하는 property 에 underscore(_)
를 사용하여 구분하지 않았을 경우 setter와 getter에서 무한루프에 빠지게 된다.super class
또는 base class
sub class
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
// 동물 클래스를 상속받는 Dog 클래스를 만든다!
class Dog extends Animal {
// 상속받을 때, speak()를 입맛에 맞게 재정의할 수 있다. 이를 overrinding 이라고 한다!
speak() {
console.log(`${this.name} barks.`);
}
}
// Dog를 만들 때는 Animal의 상속을 받은 class이기 때문에 이름을 필수로 받아야 한다!
let dog = new Dog("cutie");
// speak는 'makes a noise'가 아니라, 'barks'가 출력된다.
dog.speak(); // "cutie barks."
extends
키워드를 사용하여 상속받을 클래스를 정의한다.// 새로운 Car class 정의
class Car {
constructor(modelName, modelYear, type, price) {
this.modelName = modelName;
this.modelYear = modelYear;
this.type = type;
this.price = price;
}
// 클락션을 울리는 메서드
makeNoise() {
console.log(`${this.modelYear}에 생산된 ${this.modelName}: 빵!`);
}
}
class ElectronicCar extends Car {
// 재정의가 필요하다면 서브 클래스에도 ㅇconstructor 써주어야 한다.
constructor(modelName, modelYear, price, chargeTime) {
// Car (부모 클래스) 에도 알려주기!
// 부모와 자식의 constructor가 다르기 때문에 맞춰주기 위해 super 키워드 사용
super(modelName, modelYear, "e", price);
this._chargeTime = chargeTime;
}
}
// 자동차 만들기
const car1 = new Car("Sorento", "2023", "h", 5000);
const car2 = new Car("SM5", "1999", "g", 3000);
car1.makeNoise(); // 2023에 생산된 Sorento: 빵!
car2.makeNoise(); // 1999에 생산된 SM5: 빵!
// 전기 자동차 만들기
const eleCar1 = new ElectronicCar("tesla", "2023", 9000, "60min");
eleCar1.makeNoise(); // 2023에 생산된 tesla: 빵!
eleCar1.chargeTime = "20min";
console.log(eleCar1.chargeTime); // 20min
super
를 호출하면 부모 클래스의 constructor를 호출한다.💡 [
super
호출 시 주의사항]
- 서브 클래스에서 constructor를 생략하지 않는 경우 서브클래스의 constructor에서는 반드시 super를 호출해야 한다.
- 서브클래스의 constructor에서 super를 호출하기 전에는 this를 참조할 수 없다.
- super는 반드시 서브클래스의 constructor에서만 호출한다. 서브클래스가 아닌 클래스의 constructor나 함수에서 super를 호출하면 에러가 발생한다.
class Calculator {
static add(a, b) {
return a + b;
}
static subtract(a, b) {
return a - b;
}
}
console.log(Calculator.add(1, 2)); // 3
console.log(Calculator.subtract(3, 2)); // 1
static
이라는 키워드를 사용하여 클래스 레벨의 메서드를 정의할 수 있다.클래스 개념은 익숙해서 이해하는게 어렵지는 않았는데... 뒤에서 만날 클로저 개념이 잘 와닿지 않았다. 글로 정리를 해봐야 머릿 속에서 정리될 것 같다. 🤯