📘 15.3.2 부모님께 도움 요청하기 - 가족의 힘을 빌리는 특별한 방법
따스한 오후, 창가에 앉아 지난 시간을 떠올려보세요. 우리는 extends
라는 온화한 단어를 통해 부모 클래스의 지혜가 자식 클래스에게 자연스럽게 전해지는 아름다운 순간을 경험했습니다. 그런데 가만히 생각해보니, 자식 클래스가 부모 클래스의 품 안에서 "도움이 필요해요"라고 말할 수 있는 방법이 있을까요?
마치 어린 시절, 혼자 풀기 어려운 숙제 앞에서 부모님께 조심스럽게 손을 내밀었던 그 순간처럼요. 오늘은 바로 그런 부모님께 도움 요청하기의 따뜻한 이야기를 함께 나누어보겠습니다.
🧠 새로운 단어들과 친해지기
부모님께 도움을 요청하는 이 소중한 순간을 이해하기 위해, 몇 가지 따뜻한 단어들을 먼저 만나보겠습니다.
단어 | 쉬운 설명 |
---|---|
super | 부모 클래스의 만들기 도우미나 기능을 부를 때 사용하는 특별한 단어예요 |
super() | 부모 클래스의 만들기 도우미를 부르는 방법이에요 |
super.기능() | 부모 클래스의 기능을 부르는 방법이에요 |
만들기 도우미 연결 | 자식부터 부모까지 연결된 만들기 도우미 부르기 과정이에요 |
super
라는 단어 안에는 "위의", "상위의"라는 뜻이 조용히 숨어있습니다. 부모 클래스를 "상위 클래스"라고도 부르니까요. 위에 계신 부모님의 따뜻한 도움을 청한다는 의미가 그 안에 고스란히 담겨있는 것 같아요.
✨ 부모님께 도움 요청하기의 핵심 개념
부모님께 도움을 요청하는 일은, 자식 클래스가 부모 클래스와 소통하는 특별한 창구 역할을 합니다. 집 안에서 부모님께 도움이 필요할 때 "엄마", "아빠"라고 부르듯이, 프로그래밍 세계에서는 super
라고 불러드리면 부모 클래스가 따뜻하게 응답해주지요.
super 키워드는 두 가지 섬세한 방식으로 사용됩니다. 첫 번째는 super()
형태로 부모 클래스의 만들기 도우미를 불러드리는 것입니다. 이는 자식 물건이 세상에 태어날 때 부모 물건도 함께 올바르게 준비되도록 하는, 참으로 중요한 역할을 담당합니다.
두 번째는 super.기능()
형태로 부모 클래스의 특정 기능을 조심스럽게 불러드리는 것입니다. 이를 통해 부모님의 지혜를 그대로 받아들이면서도, 자식만의 새로운 빛깔을 더할 수 있어요.
super의 가장 소중한 특징은 자식 클래스에서만 사용할 수 있다는 점입니다. 특징 물려받기 관계가 없다면 super를 사용할 수 없어요. 마치 가족이 아니면 "엄마", "아빠"라고 부를 수 없는 것처럼요.
재미있는 비유: 부모님께 도움 요청하기
부모님께 도움을 요청하는 이 과정을 더 따뜻하게 이해하기 위해 '가족의 도움 요청'에 비유해볼게요.
어린 아이가 아침에 학교 준비를 하는 모습을 상상해보세요. 혼자서도 할 수 있는 일들이 있지만, 때로는 부모님의 도움이 간절히 필요한 순간들이 있습니다. 예를 들어 아침식사 준비같은 일은 부모님께 "엄마, 아침 준비 도와주세요"라고 조심스럽게 부탁할 수 있지요.
그러면 엄마는 밥을 짓고, 반찬을 차리고, 정리까지 모든 기본 준비를 정성스럽게 해주십니다. 그 다음에 아이는 자신만의 특별한 일을 조용히 추가할 수 있어요. 식탁을 예쁘게 꾸미거나, 좋아하는 간식을 살며시 준비하는 것처럼요.
또한 평소에 엄마가 해주시던 '방 정리'도 함께 도움받을 수 있습니다. "엄마, 평소처럼 방 정리 도와주세요"라고 말하면 엄마는 기본적인 정리를 차분히 해주시고, 아이는 거기에 자신만의 방식으로 소중한 꾸미기를 더할 수 있지요.
프로그래밍에서 super도 정확히 이와 같습니다. 부모 클래스에게 "기본적인 일 해주세요"(super()
)라고 정중히 부탁하거나, "평소 하시던 일 도와주세요"(super.기능()
)라고 요청해서 부모님의 따뜻한 도움을 받는 것이에요.
🎯 super를 사용하는 이유
그렇다면 우리는 왜 super를 사용하게 될까요? 여러 소중한 이유들이 있습니다.
첫째로 부모 클래스의 준비하기 기능을 재사용할 수 있습니다. 자식 클래스를 만들 때 부모 클래스에서 이미 정성스럽게 만들어진 준비하기 코드를 다시 작성할 필요 없이 super()
로 간단히 불러올 수 있어요.
둘째로 코드 중복을 줄일 수 있습니다. 부모 클래스의 기능이 이미 필요한 기능을 제공한다면, 그 기능을 처음부터 다시 만들지 않고 super.기능()
으로 불러온 후 추가 기능만 살며시 더하면 됩니다.
셋째로 관리가 쉬워집니다. 부모 클래스의 기능이 개선되면 super를 사용하는 모든 자식 클래스들도 자동으로 개선된 기능을 사용하게 되어, 관리가 한결 편해집니다.
마지막으로 안전한 준비하기가 가능합니다. super()
를 불러드리면 부모 클래스가 올바르게 준비된 후에 자식 클래스의 추가 작업이 수행되므로, 안정적인 물건 만들기가 보장되지요.
⚙️ 기본 사용법 살펴보기
super 키워드의 기본 사용법을 차근차근 살펴보겠습니다.
// 부모 클래스
class 부모클래스 {
constructor(받을정보) {
this.정보 = 받을정보;
}
기능() {
// 부모 기능 내용
}
}
// 자식 클래스
class 자식클래스 extends 부모클래스 {
constructor(받을정보, 추가정보) {
super(받을정보); // 부모 만들기 도우미 부르기
this.추가정보 = 추가정보;
}
기능() {
super.기능(); // 부모 기능 부르기
// 추가 내용
}
}
super() 사용 규칙:
- 자식 클래스의 constructor 첫 줄에서만 사용 가능
- 부모 클래스의 만들기 도우미에 필요한 정보 전달
- 반드시 this 사용 전에 불러야 함
super.기능() 사용 규칙:
- 자식 클래스의 어떤 기능에서든 사용 가능
- 부모 클래스의 같은 이름 기능 부르기
- 부르는 위치는 자유롭게 결정 가능
🧪 직접 해보면서 배우기
이제 실제 예시를 통해 super 키워드가 어떻게 조용히 동작하는지 자세히 알아보겠습니다.
🔹 첫 번째 예시: super() 만들기 도우미 부르기 이해하기
첫 번째로는 super()를 사용해서 부모 만들기 도우미를 정중히 불러드리는 방법을 알아보겠습니다.
// 부모 클래스: 동물
class Animal {
constructor(name, age) {
this.name = name; // 이름 저장하기
this.age = age; // 나이 저장하기
this.energy = 100; // 에너지를 100으로 시작하기
console.log("동물 " + name + "(" + age + "살)이 만들어졌어요!");
}
eat() {
if (this.energy + 20 > 100) {
this.energy = 100; // 에너지가 100을 넘지 않게 하기
} else {
this.energy = this.energy + 20; // 에너지 20 늘리기
}
console.log(this.name + "이(가) 먹이를 먹었어요! 에너지: " + this.energy);
}
}
// 자식 클래스: 강아지
class Dog extends Animal {
constructor(name, age, breed) {
// 먼저 부모 만들기 도우미 부르기
super(name, age);
// 강아지만의 추가 정보
this.breed = breed; // 품종 저장하기
this.loyalty = 100; // 충성도를 100으로 시작하기
console.log(breed + " 강아지 " + name + "이(가) 만들어졌어요!");
}
bark() {
if (this.energy - 10 < 0) {
this.energy = 0; // 에너지가 0 아래로 내려가지 않게 하기
} else {
this.energy = this.energy - 10; // 에너지 10 소모
}
console.log(this.name + ": 멍멍! (에너지: " + this.energy + ")");
}
}
// 물건 만들기 및 super() 부르기 과정 확인하기
console.log("=== 강아지 만들기 (super 부르기 과정) ===");
let myDog = new Dog("멍멍이", 3, "골든리트리버");
// 부모로부터 물려받은 정보와 기능 사용하기
console.log("강아지 이름: " + myDog.name + " (" + myDog.age + "살)");
console.log("품종: " + myDog.breed);
myDog.eat(); // 부모 기능
myDog.bark(); // 자식 기능
이 과정을 가만히 살펴보면, new Dog()
를 부르면 먼저 자식 만들기 도우미가 조용히 시작되고, 첫 줄의 super(name, age)
가 부모 만들기 도우미를 따뜻하게 불러드립니다. 부모 만들기 도우미가 끝난 후에 자식 만들기 도우미의 나머지 부분이 차분히 실행되어 강아지만의 소중한 정보들이 추가되지요.
🔹 두 번째 예시: super.기능()으로 부모 기능 활용하기
이번에는 super.기능()을 사용해서 부모 기능을 자연스럽게 확장하는 방법을 알아보겠습니다.
// 부모 클래스: 차량
class Vehicle {
constructor(brand, model) {
this.brand = brand; // 브랜드 저장하기
this.model = model; // 모델 저장하기
this.speed = 0; // 속도를 0으로 시작하기
this.running = false; // 시동 상태를 꺼진 상태로 시작하기
}
start() {
this.running = true; // 시동 켜기
console.log(this.brand + " " + this.model + " 시동을 걸었어요.");
}
accelerate(amount) {
if (!this.running) { // 시동이 꺼져 있으면
console.log("시동이 꺼져 있어요. 먼저 시동을 걸어주세요.");
return;
}
this.speed = this.speed + amount; // 속도 늘리기
console.log("속도가 " + amount + "km/h 늘어났어요. 현재 속도: " + this.speed + "km/h");
}
}
// 자식 클래스: 전기차
class ElectricCar extends Vehicle {
constructor(brand, model, batteryCapacity) {
// 부모 만들기 도우미 부르기
super(brand, model);
// 전기차만의 정보
this.batteryCapacity = batteryCapacity; // 배터리 용량 저장하기
this.batteryLevel = 100; // 배터리를 100%로 시작하기
}
// 부모 기능 확장하기
start() {
// 부모 기능 부르기
super.start();
// 추가 기능
console.log("🔋 배터리 확인: " + this.batteryLevel + "%");
console.log("⚡ 전기 모터 준비 완료!");
}
// 부모 기능 확장하기
accelerate(amount) {
// 배터리 확인하기
if (this.batteryLevel <= 0) {
console.log("배터리가 없어요. 충전이 필요해요.");
return;
}
// 부모 기능 부르기
super.accelerate(amount);
// 추가 기능 (배터리 소모)
this.batteryLevel = this.batteryLevel - (amount / 10);
if (this.batteryLevel < 0) {
this.batteryLevel = 0; // 배터리가 0 아래로 내려가지 않게 하기
}
console.log("⚡ 배터리 잔량: " + this.batteryLevel + "%");
}
}
// 전기차 만들고 테스트하기
console.log("=== 전기차 테스트 (super.기능() 부르기) ===");
let teslaModel3 = new ElectricCar("Tesla", "Model 3", 75);
// 확장된 기능 테스트
teslaModel3.start(); // 부모 기능 + 전기차 기능
teslaModel3.accelerate(30); // 부모 기능 + 배터리 소모
teslaModel3.accelerate(40); // 부모 기능 + 배터리 소모
이 예시에서는 자식 클래스가 부모 기능의 기능을 그대로 소중히 사용하면서도 전기차만의 특별한 기능을 자연스럽게 추가하는 모습을 볼 수 있습니다. super.start()
와 super.accelerate()
를 정중히 불러서 부모의 기본 기능을 활용한 후, 배터리 관련 기능을 조심스럽게 추가로 구현했어요.
🔹 세 번째 예시: 복합적인 super 사용 예시
마지막으로는 super의 다양한 사용법을 종합적으로 천천히 살펴보겠습니다.
// 기본 사용자 클래스
class User {
constructor(username, email) {
this.username = username; // 사용자명 저장하기
this.email = email; // 이메일 저장하기
this.active = true; // 활성 상태를 true로 시작하기
this.joinYear = 2024; // 가입 연도를 2024로 설정하기
}
login() {
if (!this.active) { // 활성 상태가 아니면
console.log("계정이 비활성화되어 있어요.");
return false;
}
console.log(this.username + " 사용자로 로그인했어요.");
return true;
}
getInfo() {
return {
username: this.username,
email: this.email,
active: this.active
};
}
}
// 학생 사용자 클래스
class StudentUser extends User {
constructor(username, email, grade, classroom) {
super(username, email); // 부모 만들기 도우미 부르기
this.grade = grade; // 학년 저장하기
this.classroom = classroom; // 반 저장하기
this.assignments = []; // 과제를 담을 바구니 만들기
}
submitAssignment(title) {
const assignment = { title: title, year: 2024 }; // 과제 정보 만들기
this.assignments.push(assignment); // 과제 바구니에 넣기
console.log("과제 \"" + title + "\" 제출 완료!");
}
// 부모 기능 확장하기
getInfo() {
// 부모의 정보 가져오기
const basicInfo = super.getInfo();
// 학생 정보 추가하기
return {
username: basicInfo.username, // 부모 정보
email: basicInfo.email, // 부모 정보
active: basicInfo.active, // 부모 정보
grade: this.grade, // 학년 추가
classroom: this.classroom, // 반 추가
assignmentCount: this.assignments.length // 과제 개수 추가
};
}
}
// 사용자들 만들고 테스트하기
console.log("=== 사용자 만들기 및 테스트 ===");
let basicUser = new User("basic_user", "basic@example.com");
let student = new StudentUser("student1", "student@school.com", 3, "3-2");
// 공통 기능 테스트
basicUser.login();
student.login();
// 특화 기능 테스트
student.submitAssignment("수학 숙제");
// getInfo 기능으로 확장된 정보 확인하기
console.log("기본 사용자:", basicUser.getInfo());
console.log("학생 사용자:", student.getInfo());
이 예시에서는 super()
로 부모 만들기 도우미를 조용히 불러드리고, super.getInfo()
로 부모 기능의 결과를 정중히 가져와서 추가 정보와 섬세하게 합치는 방법을 보여줍니다. 이런 식으로 super를 활용하면 부모의 기능을 최대한 재사용하면서도 자식만의 특별한 기능을 자연스럽게 추가할 수 있어요.
🔄 super 사용 과정 정리하기
지금까지 배운 super 사용 과정을 차근차근 정리해보겠습니다.
만들기 도우미에서의 super() 과정:
첫 번째 단계로 자식 만들기 도우미 시작에서 new 자식클래스()
가 불립니다. 두 번째 단계로 super() 부르기에서 자식 만들기 도우미의 첫 줄에서 부모 만들기 도우미를 정중히 불러드리죠. 세 번째 단계로 부모 만들기 도우미 실행에서 부모 클래스의 정보들이 차분히 준비됩니다. 마지막으로 네 번째 단계는 자식 만들기 도우미 완료에서 자식만의 추가 정보들이 조심스럽게 설정됩니다.
기능에서의 super.기능() 과정:
첫 번째 단계로 자식 기능 부르기에서 자식 물건의 기능이 실행됩니다. 두 번째 단계로 super.기능() 부르기에서 부모 클래스의 같은 이름 기능을 정중히 불러드리죠. 세 번째 단계로 부모 기능 실행에서 부모의 기능이 정성스럽게 수행됩니다. 마지막으로 네 번째 단계는 자식 추가 작업에서 자식만의 추가 기능이 조용히 실행됩니다.
🧚♀️ 이야기로 다시 배우기: 요리하는 가족
지금까지 배운 내용을 하나의 따뜻한 이야기로 다시 정리해볼까요?
어느 요리를 사랑하는 가족이 있었습니다. 할머니는 전통 요리의 대가였고, 수십 년간 갈고닦은 기본 요리법들을 마음속 깊이 간직하고 계셨어요. 밥 짓기, 국 끓이기, 반찬 만들기 등 모든 기초가 정말 완벽했죠.
손녀는 할머니의 요리를 정성껏 배우면서도 현대적인 감각을 조심스럽게 더하고 싶어했습니다. 그래서 요리할 때마다 "할머니, 기본 요리법 알려주세요"라고 정중히 부탁했어요. (super()
부르기)
할머니가 기본 준비를 모두 정성스럽게 해주시면, 손녀는 거기에 자신만의 특별한 양념이나 플레이팅을 살며시 추가했습니다. 예를 들어 할머니의 전통 미역국에 현대적인 고명을 조심스럽게 올리거나, 기본 밑반찬에 예쁜 그릇과 장식을 정성껏 더하는 식으로 말이에요.
때로는 할머니가 해주시던 특별한 요리법도 함께 배웠습니다. "할머니, 평소 하시던 그 양념 만드는 법 알려주세요"라고 조심스럽게 부탁하면 (super.기능()
부르기), 할머니는 전통 양념법을 정성껏 가르쳐 주시고, 손녀는 거기에 현대적인 재료를 조금 더해서 새로운 맛을 조용히 만들어냈어요.
이처럼 super는 선조의 지혜를 소중히 물려받으면서도 새로운 시대에 맞게 자연스럽게 발전시키는 프로그래밍의 아름다운 요리법인 것입니다.
🧠 자주 하는 실수와 주의할 점
super를 사용할 때 자주 발생하는 실수들을 미리 알아두면 더 안전한 코딩을 할 수 있어요.
❌ 실수 1: super() 부르는 것을 잊거나 늦게 부르기
class Animal {
constructor(name) {
this.name = name; // 이름 저장하기
}
}
// 잘못된 예시 1 - super() 부르기 누락
class BadDog extends Animal {
constructor(name, breed) {
// super(name); // 이걸 빼먹음! 에러가 날 거예요!
this.breed = breed;
}
}
// 잘못된 예시 2 - super() 늦게 부르기
class LateDog extends Animal {
constructor(name, breed) {
this.breed = breed; // this 사용 전에 super()를 불러야 해요! 에러가 날 거예요!
super(name);
}
}
// 올바른 예시 - super() 먼저 부르기
class GoodDog extends Animal {
constructor(name, breed) {
super(name); // 올바른 위치!
this.breed = breed;
}
}
try {
let goodDog = new GoodDog("멍멍이", "진돗개"); // 정상 작동
console.log("정상 생성된 강아지:", goodDog.name, goodDog.breed);
} catch (error) {
console.log("에러 발생:", error.message);
}
이런 실수가 발생하는 이유는 자식 클래스에서 this
를 사용하기 전에 반드시 부모 클래스가 차분히 준비되어야 하기 때문입니다. super()
가 그 중요한 역할을 담당하므로 첫 줄에서 정중히 불러야 해요.
❌ 실수 2: 부모 기능을 완전히 무시하고 다시 만들기
class Animal {
constructor(name) {
this.name = name; // 이름 저장하기
this.energy = 100; // 에너지를 100으로 시작하기
}
eat() {
if (this.energy + 20 > 100) {
this.energy = 100; // 에너지가 100을 넘지 않게 하기
} else {
this.energy = this.energy + 20; // 에너지 20 늘리기
}
console.log(this.name + "이(가) 음식을 먹고 에너지가 " + this.energy + "가 되었어요.");
}
}
// 잘못된 예시 - 부모 기능을 완전히 덮어쓰기
class BadCat extends Animal {
eat() {
// super.eat() 부르기 없이 완전히 다시 만들기
console.log(this.name + " 고양이가 먹이를 먹었어요~");
// energy 늘리기 로직이 빠짐! 버그가 생길 수 있어요
}
}
// 올바른 예시 - 부모 기능 부르기 후 확장
class GoodCat extends Animal {
eat() {
// 부모 기능 부르기로 기본 기능 유지하기
super.eat();
// 추가 기능
console.log(this.name + " 고양이가 만족스럽게 그르렁거려요~");
}
}
let badCat = new BadCat("나비");
let goodCat = new GoodCat("미야");
console.log("=== BadCat 테스트 ===");
badCat.eat(); // 에너지가 늘어나지 않아요!
console.log("BadCat 에너지:", badCat.energy); // 여전히 100
console.log("\n=== GoodCat 테스트 ===");
goodCat.eat(); // 에너지가 늘어나고 추가 메시지도 출력
console.log("GoodCat 에너지:", goodCat.energy); // 100 (이미 최대값)
이런 실수를 피하려면 부모 기능의 중요한 기능을 소중히 유지하면서 추가 기능을 구현하는 것이 좋습니다. super.기능()
을 정중히 부른 후 추가 작업을 하는 방식이 안전해요.
❌ 실수 3: 부모 클래스에 없는 정보를 super()에 전달하기
class Vehicle {
constructor(brand, model) {
this.brand = brand; // 브랜드 저장하기
this.model = model; // 모델 저장하기
}
}
// 잘못된 예시 - 부모가 사용하지 않는 정보 전달
class BadCar extends Vehicle {
constructor(brand, model, color) {
super(brand, model, color); // color는 부모에서 사용하지 않아요!
this.color = color;
}
}
// 올바른 예시 - 부모가 필요한 정보만 전달
class GoodCar extends Vehicle {
constructor(brand, model, color) {
super(brand, model); // 부모에게 필요한 정보만 정중히 전달
this.color = color;
}
}
let badCar = new BadCar("현대", "소나타", "빨간색");
console.log("BadCar:", badCar); // 동작은 하지만 불필요한 정보 전달
let goodCar = new GoodCar("기아", "K5", "파란색");
console.log("GoodCar:", goodCar); // 올바른 방식
부모 클래스의 만들기 도우미가 필요로 하는 정보만 정확히 전달하는 것이 코드를 명확하고 이해하기 쉽게 만들어줍니다.
✏️ 연습문제로 개념 다지기
코드 위의 시간이 조용히 흘러간 지금, 배운 내용을 연습문제를 통해 차분히 익혀보겠습니다.
Ex1) super()를 사용하여 간단한 특징 물려받기 관계를 만들어보자
// 부모 클래스: 도형
class Shape {
constructor(color) {
if (color) {
this.color = color; // 색깔이 주어지면 저장하기
} else {
this.color = "검정"; // 주어지지 않으면 검정으로 하기
}
this.name = "도형"; // 이름을 "도형"으로 설정하기
}
describe() {
console.log("이것은 " + this.color + " " + this.name + "이에요.");
}
}
// 자식 클래스: 사각형
class Rectangle extends Shape {
constructor(color, width, height) {
// 부모 만들기 도우미 부르기
super(color);
// 추가 정보 설정하기
this.name = "사각형"; // 부모 정보 다시 설정하기
this.width = width; // 가로 저장하기
this.height = height; // 세로 저장하기
}
// 면적 계산 기능
getArea() {
return this.width * this.height; // 가로 × 세로
}
}
// 물건 만들고 테스트하기
let shape = new Shape("파란");
let rect = new Rectangle("빨간", 5, 3);
shape.describe(); // 이것은 파란 도형이에요.
rect.describe(); // 이것은 빨간 사각형이에요.
console.log("사각형의 넓이:", rect.getArea()); // 15
이 연습을 통해 super()
가 부모 만들기 도우미를 정중히 불러서 기본 준비를 수행하는 방법을 익힐 수 있습니다.
Ex2) super.기능()을 사용하여 부모 기능을 확장하는 예제를 만들어보자
어느 고요한 시간, 우리는 은행 통장의 이야기를 통해 super 기능을 배워보겠습니다.
// 부모 클래스: 통장
class BankAccount {
constructor(owner, balance) {
this.owner = owner; // 계좌 주인 저장하기
if (balance) {
this.balance = balance; // 잔액이 주어지면 저장하기
} else {
this.balance = 0; // 주어지지 않으면 0으로 하기
}
this.transactions = []; // 거래 내역을 담을 바구니 만들기
}
deposit(amount) {
if (amount <= 0) { // 0보다 작거나 같으면
console.log("넣을 돈은 0보다 커야 해요.");
return false;
}
this.balance = this.balance + amount; // 잔액에 돈 더하기
this.transactions.push("돈 넣기: " + amount + "원"); // 거래 내역에 기록하기
console.log(amount + "원 넣기 완료. 잔액: " + this.balance + "원");
return true;
}
getStatement() {
console.log("\n===== " + this.owner + "님의 계좌 정보 =====");
console.log("잔액: " + this.balance + "원");
console.log("거래 내역:");
for (let i = 0; i < this.transactions.length; i++) {
console.log("- " + this.transactions[i]);
}
}
}
// 자식 클래스: 적금 통장
class SavingsAccount extends BankAccount {
constructor(owner, balance, interestRate) {
super(owner, balance); // 부모 만들기 도우미 부르기
if (interestRate) {
this.interestRate = interestRate; // 이자율이 주어지면 저장하기
} else {
this.interestRate = 0.05; // 주어지지 않으면 0.05로 하기
}
this.interestEarned = 0; // 받은 이자를 0으로 시작하기
}
// 부모 기능 확장하기
deposit(amount) {
// 부모 기능 부르기
const success = super.deposit(amount);
if (success) {
// 추가 기능: 입금 보너스
const bonus = amount * 0.01; // 1% 보너스 계산하기
const bonusRounded = Math.floor(bonus); // 소수점 버리기
if (bonusRounded > 0) {
this.balance = this.balance + bonusRounded; // 보너스 추가하기
this.transactions.push("입금 보너스: " + bonusRounded + "원"); // 보너스 기록하기
console.log("🎁 보너스 " + bonusRounded + "원이 추가되었어요!");
}
}
return success;
}
// 부모 기능 확장하기
getStatement() {
// 부모 기능 부르기
super.getStatement();
// 추가 정보 보여주기
console.log("이자율: " + (this.interestRate * 100) + "%");
console.log("지금까지 받은 이자: " + this.interestEarned + "원");
}
}
// 적금 통장 만들고 테스트하기
let savings = new SavingsAccount("철수", 1000, 0.08);
savings.deposit(5000); // 부모 기능 + 추가 보너스
savings.getStatement(); // 부모 기능 + 추가 정보
이 문제는 super.기능()
을 사용해서 부모의 기능을 소중히 활용하면서 자식만의 추가 기능을 자연스럽게 구현하는 방법을 연습하는 데 도움이 됩니다.
🤔 조금 더 어려운 문제로 실력 확인하기
기본 연습을 조용히 마쳤다면, 이제 조금 더 깊이 있는 문제들을 통해 super에 대한 이해를 차분히 확인해보겠습니다.
Q1. super() 부르기가 필요한 이유와 위치에 대해 설명해보세요.
정답: super() 부르기는 자식 클래스의 만들기 도우미에서 부모 클래스의 만들기 도우미를 정중히 불러드리기 위해 필요합니다. 반드시 자식 만들기 도우미의 첫 줄에서 불러야 하는데, 이는 this
키워드를 사용하기 전에 부모 클래스의 준비하기가 먼저 완료되어야 하기 때문입니다. super()
를 부르지 않거나 늦게 부르면 "this is not defined" 같은 에러가 발생합니다.
Q2. super.기능()을 부르는 것의 장점을 2가지 설명해보세요.
정답: 첫째, 코드 중복을 줄일 수 있습니다. 부모 기능의 기능을 그대로 다시 작성하는 대신 부르기만 하면 되기 때문에 코드가 간결해집니다. 둘째, 관리가 쉬워집니다. 부모 기능이 바뀌면 자식 기능도 자동으로 업데이트된 기능을 사용하게 되어, 모든 코드를 일일이 수정할 필요가 없습니다.
📚 복습 문제 - 이전에 배운 내용 기억하기
이제 이전 단원에서 배운 중요한 내용들을 복습해보며 기억을 새롭게 해볼게요!
🔄 복습 1: 클래스와 상속 기본 개념 (15.1, 15.3.1 단원 복습)
// 문제: 다음 코드에서 빈 칸을 채워 Animal 클래스와 Cat 클래스를 완성해보세요.
// 부모 클래스: 동물
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
this.energy = 100;
}
sleep() {
this.energy = 100;
console.log(this.name + "이(가) 잠을 자고 에너지가 완전히 충전되었어요!");
}
}
// 자식 클래스: 고양이 - 빈 칸을 채워주세요!
class Cat ______ Animal { // 빈 칸 1: 상속 키워드
constructor(name, age, color) {
// 빈 칸 2: 부모 생성자 호출
this.color = color;
this.cuteness = 100;
}
meow() {
console.log(this.name + ": 야옹~");
}
}
// 테스트 코드
let myCat = new Cat("나비", 2, "흰색");
myCat.meow(); // 자식 메서드
myCat.sleep(); // 부모 메서드
정답:
class Cat extends Animal {
constructor(name, age, color) {
super(name, age); // 부모 생성자 호출
this.color = color;
this.cuteness = 100;
}
meow() {
console.log(this.name + ": 야옹~");
}
}
해설: 상속을 위해서는 extends
키워드를 사용하고, 자식 클래스의 생성자에서는 반드시 super()
를 호출해서 부모 클래스를 먼저 초기화해야 합니다.
🔄 복습 2: 메서드 오버라이딩 (15.3.3 단원 내용 미리보기)
// 문제: 다음 코드에서 Dog 클래스가 Animal의 sleep 메서드를 확장하도록 만들어보세요.
class Animal {
constructor(name) {
this.name = name;
this.energy = 50;
}
sleep() {
this.energy = 100;
console.log(this.name + "이(가) 잠을 잤어요.");
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
// 여기에 sleep 메서드를 확장해서 만들어보세요!
// 부모의 sleep 기능은 유지하면서,
// "강아지가 꼬리를 흔들며 일어났어요!" 메시지를 추가해주세요.
}
// 테스트
let myDog = new Dog("멍멍이", "골든리트리버");
myDog.sleep(); // 부모 메시지 + 추가 메시지가 모두 나와야 해요!
정답:
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
sleep() {
super.sleep(); // 부모 메서드 호출
console.log("강아지가 꼬리를 흔들며 일어났어요!");
}
}
해설: 부모 메서드의 기능을 유지하면서 추가 기능을 더하려면 super.메서드()
를 먼저 호출한 후 자식만의 코드를 추가하면 됩니다.
지금까지 super 키워드의 모든 특성과 활용법을 자세히 알아보았습니다. super는 특징 물려받기 관계에서 부모와 자식 클래스를 연결하는 중요한 다리 역할을 하며, 코드의 재사용성과 관리 편의성을 크게 향상시켜주는 핵심 기능입니다.
✅ 학습 완료 체크리스트
이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요!
학습 내용 | 이해했나요? |
---|---|
super 키워드의 기본 개념 | ✅ |
super()와 super.메서드() 차이점 | ✅ |
부모 클래스 호출 순서와 규칙 | ✅ |
자주 하는 실수들과 해결법 | ✅ |
실전 예제 이해 | ✅ |
📂 마무리 정보
오늘 배운 15.3.2
내용이 여러분의 자바스크립트 지식 상자에 잘 저장되었나요? 다음 시간에는 더 재미있는 내용으로 만나요!
기억할 점: super는 상속에서 부모와 자식을 연결하는 중요한 다리예요. 꼭 연습해보시고, 궁금한 점이 있으면 언제든 다시 돌아와서 읽어보세요.
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
'15. 클래스로 틀 만들기 (클래스) > 15.3 상속 (Inheritance)' 카테고리의 다른 글
15.3.3 나만의 방식으로 바꾸기 - 부모님 방식을 내 스타일로 개선하는 특별한 기술 (0) | 2025.07.23 |
---|---|
15.3.1 부모의 특징을 물려받기 - 가족처럼 연결되는 특별한 방법 (0) | 2025.07.23 |