15. 클래스로 틀 만들기 (클래스)/15.2 인스턴스 생성하기

15.2.2 인스턴스 속성과 메서드 - 각 객체의 개인 정보와 특별한 능력들

thejavascript4kids 2025. 7. 22. 02:57

📘 15.2.2 인스턴스 속성과 메서드 - 각 객체의 개인 정보와 특별한 능력들

여러분, 안녕하세요. 지난 시간에 new 키워드로 클래스로부터 실제 객체를 만드는 방법을 배웠습니다. 이제는 그 객체들이 가지고 있는 특별한 능력들을 자세히 알아볼 차례예요. 각 객체가 가지는 자신만의 정보와 자신만의 기능이 바로 인스턴스 속성과 메서드랍니다.

마치 각 친구가 자신만의 학용품과 능력을 가지고 있는 것처럼, 모든 객체도 자신만의 정보 저장공간과 자신만의 기능을 가지고 있어요. 이번 시간에는 이런 개별적인 능력들을 어떻게 사용하고 관리하는지 함께 배워보겠습니다.

🧠 새로운 단어들과 친해지기

각 객체의 개별적인 특성을 다룰 때 자주 사용되는 중요한 단어들을 살펴보겠습니다.

단어 쉬운 설명
인스턴스 속성 각 객체가 개별적으로 가지는 정보(변수)예요
인스턴스 메서드 각 객체가 개별적으로 사용할 수 있는 기능이에요
속성 접근 객체의 정보를 보거나 바꾸는 것을 뜻해요
캡슐화 관련된 정보와 기능을 하나로 묶어서 관리하는 것이에요

"객체 하나하나"는 클래스로부터 만들어진 실제 객체 각각을 의미해요. 마치 학교 등록 양식으로 등록한 실제 학생 한 명이 하나의 인스턴스인 것처럼 말이에요.

✨ 인스턴스 속성과 메서드의 핵심 개념

인스턴스 속성과 메서드는 클래스 프로그래밍의 핵심 아이디어 중 하나예요. 각 객체가 자신만의 정보를 가지고, 자신만의 방식으로 그 정보를 다룰 수 있다는 거죠.

인스턴스 속성은 각 객체의 개인 서랍 같은 역할을 해요. 같은 클래스로 만든 여러 객체라도 각자 다른 정보들을 자신의 서랍에 저장할 수 있어요. 철수 객체는 이름이 "철수"이고 성적이 85점일 수 있고, 영희 객체는 이름이 "영희"이고 성적이 92점일 수 있어요.

인스턴스 메서드는 각 객체의 개인 도구상자 같은 역할을 해요. 모든 객체가 "공부하기", "시험보기", "성적확인하기" 같은 기능을 가지고 있지만, 각자 자신의 정보에만 영향을 줘요. 철수가 공부하기 기능을 사용하면 철수의 성적만 올라가고, 영희의 성적은 변하지 않아요.

재미있는 비유: 개인 스마트폰

인스턴스 속성과 메서드를 '개인 스마트폰'에 비유해볼게요.

여러분과 친구들이 모두 같은 모델의 스마트폰을 가지고 있다고 상상해보세요. 겉모습은 똑같지만, 각자의 폰 안에는 완전히 다른 내용들이 들어있을 거예요.

각자의 속성(데이터):

  • 철수 폰: 사진 100장, 앱 50개, 배터리 80%, 전화번호 010-1234-5678
  • 영희 폰: 사진 200장, 앱 30개, 배터리 45%, 전화번호 010-2345-6789
  • 민수 폰: 사진 50장, 앱 80개, 배터리 95%, 전화번호 010-3456-7890

각자의 메서드(능력):

  • 사진찍기() → 자신의 사진 개수 늘리기
  • 앱설치() → 자신의 앱 개수 늘리기, 자신의 배터리 줄이기
  • 전화걸기() → 자신의 전화번호로 발신하기

중요한 건 철수가 사진을 찍어도 영희 폰의 사진은 늘어나지 않고, 민수가 앱을 설치해도 다른 친구들의 앱은 설치되지 않는다는 거예요. 각자의 폰이 독립적으로 동작하는 거죠.

🎯 인스턴스 속성과 메서드를 배우는 이유

인스턴스 속성과 메서드를 배우는 이유는 정말 실용적이에요.

첫 번째로 각 객체를 개별적으로 관리할 수 있어요. 게임에서 캐릭터 100명을 만들었다면, 각 캐릭터가 다른 체력, 다른 위치, 다른 상태를 가질 수 있어요. 한 캐릭터가 공격받아도 다른 캐릭터들에게는 영향을 주지 않죠.

두 번째로 정보와 기능을 체계적으로 묶어서 관리할 수 있어요. 은행 계좌라면 잔액, 계좌번호, 소유자 같은 정보와 입금, 출금, 잔액조회 같은 기능을 하나로 묶어서 안전하게 관리할 수 있어요.

세 번째로 코드를 더 쉽게 이해할 수 있게 만들 수 있어요. student.study()라고 쓰면 "학생이 공부한다"는 의미가 바로 전달되죠. 이런 방식으로 코딩하면 프로그램의 의도를 쉽게 파악할 수 있어요.

⚙️ 기본 사용법 살펴보기

인스턴스 속성과 메서드를 사용하는 방법은 생각보다 간단해요.

클래스에서 속성과 메서드 정의하기:

class 클래스이름 {
    constructor(받을정보들) {
        // 인스턴스 속성 정의
        this.속성1 = 값1;
        this.속성2 = 값2;
    }

    // 인스턴스 메서드 정의
    메서드1() {
        // this.속성1 접근 가능
        return this.속성1;
    }

    메서드2(받을값) {
        // this.속성2 바꾸기 가능
        this.속성2 = 받을값;
    }
}

객체에서 속성과 메서드 사용하기:

let 내객체 = new 클래스이름(정보들);

// 속성 접근하기
console.log(내객체.속성1);      // 속성 읽기
내객체.속성2 = 새값;           // 속성 바꾸기

// 메서드 사용하기
내객체.메서드1();              // 메서드 실행
내객체.메서드2(값);            // 정보와 함께 메서드 실행

여기서 가장 중요한 건 this 키워드예요. 메서드 안에서 this는 "현재 이 메서드를 사용한 객체"를 가리켜요.

🧪 직접 해보면서 배우기

이제 실제 예시를 통해 인스턴스 속성과 메서드가 어떻게 동작하는지 자세히 살펴보겠습니다.

🔹 첫 번째 예시: 기본적인 속성과 메서드 활용하기

첫 번째로는 학생 클래스를 만들어서 각 객체가 어떻게 개별적인 속성을 관리하는지 확인해보겠습니다.

// 학생 클래스 만들기
class Student {
    constructor(name, grade) {
        // 각 객체가 개별적으로 가질 속성들
        this.name = name;             // 이름 저장하기
        this.grade = grade;           // 학년 저장하기
        this.subjects = [];           // 과목들을 담을 배열 만들기
        this.totalScore = 0;          // 총 점수를 0으로 시작하기
        this.attendance = 0;          // 출석일수를 0으로 시작하기
    }

    // 과목 추가 메서드 (자신의 과목 목록에만 추가)
    addSubject(subject, score) {
        this.subjects.push(subject);              // 자신의 과목 배열에 과목 넣기
        this.totalScore = this.totalScore + score;  // 자신의 총점에 점수 더하기
        console.log(`${this.name}: ${subject} 과목 ${score}점 추가됨`);
    }

    // 출석 메서드 (자신의 출석일수만 늘리기)
    attend() {
        this.attendance = this.attendance + 1;   // 자신의 출석일수 1 늘리기
        console.log(`${this.name} 출석! (총 ${this.attendance}일)`);
    }

    // 평균 점수 계산 메서드 (자신의 점수만 계산)
    getAverage() {
        if (this.subjects.length === 0) return 0;   // 과목이 없으면 0 돌려주기
        return this.totalScore / this.subjects.length;  // 총점을 과목수로 나누기
    }
}

// 여러 객체 만들고 각각 다른 정보로 관리하기
let student1 = new Student("철수", 4);    // 4학년 철수 만들기
let student2 = new Student("영희", 5);    // 5학년 영희 만들기

// 각 객체의 메서드는 자신의 속성에만 영향을 줘요
student1.addSubject("수학", 85);    // 철수에게만 수학 85점 추가
student1.addSubject("국어", 90);    // 철수에게만 국어 90점 추가
student1.attend();                  // 철수만 출석 처리

student2.addSubject("영어", 95);    // 영희에게만 영어 95점 추가
student2.attend();                  // 영희만 출석 처리
student2.attend();                  // 영희만 또 출석 처리

// 각 객체의 속성을 확인해보면 독립적으로 관리됨을 알 수 있어요
console.log(`${student1.name}의 평균 점수: ${student1.getAverage()}`);  // 87.5
console.log(`${student2.name}의 평균 점수: ${student2.getAverage()}`);  // 95
console.log(`${student1.name}의 출석일: ${student1.attendance}일`);      // 1일
console.log(`${student2.name}의 출석일: ${student2.attendance}일`);      // 2일

이 예시를 통해 각 객체가 완전히 독립적인 속성을 관리한다는 것을 확인할 수 있어요. 철수의 점수를 추가해도 영희에게는 전혀 영향을 주지 않아요.

🔹 두 번째 예시: 안전한 속성 접근과 메서드 활용

두 번째로는 은행 계좌 클래스를 만들어서 속성을 안전하게 관리하는 방법을 배워보겠습니다.

// 은행 계좌 클래스 만들기
class BankAccount {
    constructor(owner, initialBalance = 0) {
        // 각 계좌가 개별적으로 가질 속성들
        this.owner = owner;                          // 계좌 주인 저장하기
        this.balance = initialBalance;               // 잔액 저장하기
        this.accountNumber = this.generateAccountNumber();  // 계좌번호 만들어서 저장하기
        this.transactions = [];                      // 거래 내역을 담을 배열 만들기
    }

    // 계좌번호 만들기 메서드 (내부에서만 사용)
    generateAccountNumber() {
        return "ACC-" + Math.floor(Math.random() * 10000);  // 랜덤 계좌번호 만들기
    }

    // 돈 넣기 메서드 (자신의 잔액에만 영향)
    deposit(amount) {
        if (amount > 0) {                                    // 0보다 큰 금액인지 확인
            this.balance = this.balance + amount;            // 자신의 잔액에 돈 더하기
            this.transactions.push(`돈 넣기: +${amount}원`);  // 자신의 거래내역에 기록하기
            console.log(`${this.owner}님 ${amount}원 입금 완료`);
            return true;
        } else {
            console.log("입금액은 0보다 커야 해요.");
            return false;
        }
    }

    // 돈 빼기 메서드 (자신의 잔액에서만 빼기)
    withdraw(amount) {
        if (amount > 0 && amount <= this.balance) {         // 0보다 크고 잔액 이하인지 확인
            this.balance = this.balance - amount;           // 자신의 잔액에서 돈 빼기
            this.transactions.push(`돈 빼기: -${amount}원`); // 자신의 거래내역에 기록하기
            console.log(`${this.owner}님 ${amount}원 출금 완료`);
            return true;
        } else {
            console.log("출금할 수 없어요.");
            return false;
        }
    }
}

// 여러 계좌 만들고 독립적으로 관리하기
let account1 = new BankAccount("철수", 10000);    // 철수 계좌 - 10000원으로 시작
let account2 = new BankAccount("영희", 5000);     // 영희 계좌 - 5000원으로 시작

// 각 계좌의 메서드는 해당 계좌에만 영향을 줘요
account1.deposit(3000);    // 철수 계좌에 3000원 넣기
account1.withdraw(2000);   // 철수 계좌에서 2000원 빼기

account2.withdraw(1000);   // 영희 계좌에서 1000원 빼기
account2.deposit(7000);    // 영희 계좌에 7000원 넣기

// 각 계좌의 상태 확인하기
console.log(`${account1.owner}님 잔액: ${account1.balance}원`);    // 11000원
console.log(`${account2.owner}님 잔액: ${account2.balance}원`);    // 11000원
console.log(`${account1.owner}님 거래내역: ${account1.transactions.length}건`);  // 2건
console.log(`${account2.owner}님 거래내역: ${account2.transactions.length}건`);  // 2건

이 예시에서는 메서드를 통해 안전하게 속성에 접근하는 방법을 보여줘요. 직접 잔액을 바꾸는 대신 입금/출금 메서드를 사용하면 검증과 기록이 자동으로 이루어져요.

🔹 세 번째 예시: 새로운 속성 추가와 복합 메서드

세 번째로는 게임 캐릭터 클래스를 만들어서 새로운 속성을 추가하고 복합적인 메서드를 구현해보겠습니다.

// 게임 캐릭터 클래스 만들기
class GameCharacter {
    constructor(name, characterClass = "전사") {
        // 기본 속성들
        this.name = name;                    // 캐릭터 이름 저장하기
        this.characterClass = characterClass; // 캐릭터 직업 저장하기
        this.level = 1;                      // 레벨을 1로 시작하기
        this.hp = 100;                       // 체력을 100으로 시작하기
        this.exp = 0;                        // 경험치를 0으로 시작하기
        this.inventory = [];                 // 아이템들을 담을 배열 만들기
    }

    // 아이템 얻기 메서드
    addItem(item) {
        this.inventory.push(item);          // 자신의 배열에 아이템 넣기
        console.log(`${this.name}이(가) ${item}을(를) 얻었어요!`);
    }

    // 경험치 얻기 메서드
    gainExp(amount) {
        this.exp = this.exp + amount;       // 자신의 경험치에 더하기
        console.log(`${this.name} 경험치 +${amount} (총 ${this.exp})`);

        // 레벨업 확인하기 (경험치가 일정량 이상이면 레벨업)
        if (this.exp >= this.level * 100) {
            this.levelUp();                 // 레벨업 메서드 실행하기
        }
    }

    // 레벨업 메서드
    levelUp() {
        this.level = this.level + 1;        // 레벨 1 올리기
        this.hp = this.hp + 20;             // 체력 20 늘리기
        console.log(`🎉 ${this.name} 레벨업! Lv.${this.level}`);
    }
}

// 여러 캐릭터 만들고 각각 다르게 성장시키기
let warrior = new GameCharacter("용사", "전사");      // 전사 캐릭터 만들기
let mage = new GameCharacter("마법사", "마법사");     // 마법사 캐릭터 만들기

// 각 캐릭터 독립적으로 성장시키기
warrior.addItem("검");        // 용사에게 검 주기
warrior.addItem("방패");      // 용사에게 방패 주기
warrior.gainExp(150);         // 용사에게 경험치 150 주기 (레벨업!)

mage.addItem("지팡이");       // 마법사에게 지팡이 주기
mage.gainExp(80);             // 마법사에게 경험치 80 주기

// 새로운 속성을 추가로 만들어보기
warrior.specialAbility = "광전사 모드";    // 용사에게만 특별 능력 추가
mage.mana = 200;                          // 마법사에게만 마나 속성 추가

// 각 캐릭터의 최종 상태 확인하기
console.log(`${warrior.name}: Lv.${warrior.level}, 아이템 ${warrior.inventory.length}개`);
console.log(`${mage.name}: Lv.${mage.level}, 마나 ${mage.mana}`);

이 예시에서는 기본 속성 외에도 새로운 속성을 추가할 수 있다는 것을 보여줘요. 각 캐릭터가 자신만의 고유한 특성을 가질 수 있어요.

🔄 인스턴스 속성과 메서드 사용 과정 정리하기

지금까지 배운 인스턴스 속성과 메서드 사용 과정을 차근차근 정리해보겠습니다.

첫 번째 단계는 속성 준비하기입니다. constructor에서 각 객체가 가질 속성들을 this.속성이름 형태로 설정하는 것이죠.

두 번째 단계는 메서드 사용하기입니다. 만들어진 객체의 메서드를 객체.메서드이름() 형태로 불러서 작업을 수행해요.

세 번째 단계는 속성 변경하기입니다. 메서드 안에서 this.속성이름을 통해 해당 객체의 속성을 바꾸거나 확인해요.

네 번째 단계는 상태 확인하기입니다. 다른 메서드나 속성 접근을 통해 객체의 현재 상태를 확인할 수 있어요.

마지막으로 다섯 번째 단계는 결과 활용하기입니다. 바뀐 속성들을 다른 메서드나 외부 코드에서 활용할 수 있어요.

🔄 14단원 복습: 배열 메서드 되돌아보기

15단원을 배우기 전에 14단원에서 배운 고급 배열 메서드를 복습해볼까요?

복습 문제 1: map을 사용해서 새로운 배열 만들기

// 학생들의 점수 배열이 있어요
let scores = [85, 92, 78, 96, 88];

// map을 사용해서 모든 점수에 5점씩 더한 새로운 배열을 만들어보세요
let bonusScores = scores.map(function(score) {
    return score + 5;
});

console.log("원본 점수:", scores);      // [85, 92, 78, 96, 88]
console.log("보너스 점수:", bonusScores); // [90, 97, 83, 101, 93]

// 간단하게 쓰기
let quickBonus = scores.map(score => score + 5);
console.log("간단 버전:", quickBonus);

map은 배열의 모든 요소를 변환해서 새로운 배열을 만들어주는 기능이에요. 원본 배열은 그대로 두고 변환된 새 배열을 반환합니다.

복습 문제 2: filter를 사용해서 조건에 맞는 것만 골라내기

// 과일 가격 배열이 있어요
let prices = [1000, 2500, 800, 1800, 3000, 1200];

// filter를 사용해서 2000원 이하인 과일 가격만 골라내보세요
let cheapPrices = prices.filter(function(price) {
    return price <= 2000;
});

console.log("모든 가격:", prices);      // [1000, 2500, 800, 1800, 3000, 1200]
console.log("저렴한 가격:", cheapPrices); // [1000, 800, 1800, 1200]

// 간단하게 쓰기
let affordablePrices = prices.filter(price => price <= 2000);
console.log("간단 버전:", affordablePrices);

filter는 조건을 만족하는 요소들만 골라서 새로운 배열을 만들어주는 기능이에요. 조건 함수가 true를 반환하는 요소들만 새 배열에 포함됩니다.

🧠 자주 하는 실수와 주의할 점

인스턴스 속성과 메서드를 사용할 때 초보자들이 자주 하는 실수들을 미리 알아두면 더 안전한 코딩을 할 수 있어요.

❌ 실수 1: 메서드 안에서 this 없이 속성 접근하기

class Student {
    constructor(name) {
        this.name = name;      // 이름 저장하기
        this.score = 0;        // 점수를 0으로 시작하기
    }

    // 잘못된 메서드 - this 없이 속성 접근
    addScore(points) {
        score = score + points;  // this.score가 아니에요! 에러가 나요!
        console.log(`${name} 점수 증가`);  // this.name이 아니에요! 에러가 나요!
    }

    // 올바른 메서드 - this와 함께 속성 접근
    correctAddScore(points) {
        this.score = this.score + points;  // this가 꼭 필요해요!
        console.log(`${this.name} 점수: ${this.score}`);  // this가 꼭 필요해요!
    }
}

클래스 메서드 안에서 인스턴스 속성에 접근할 때는 반드시 this를 사용해야 해요. 그렇지 않으면 컴퓨터가 해당 속성을 찾을 수 없어서 에러가 발생해요.

❌ 실수 2: 다른 객체의 속성과 혼동하기

class Counter {
    constructor(name) {
        this.name = name;      // 이름 저장하기
        this.count = 0;        // 숫자를 0으로 시작하기
    }

    increment() {
        this.count = this.count + 1;     // 자신의 숫자 1 늘리기
        console.log(`${this.name} 숫자 세기: ${this.count}`);
    }
}

let counter1 = new Counter("첫 번째");      // 첫 번째 카운터 만들기
let counter2 = new Counter("두 번째");      // 두 번째 카운터 만들기

// 각 객체는 독립적인 속성을 가져요
counter1.increment();  // 첫 번째 숫자 세기: 1
counter1.increment();  // 첫 번째 숫자 세기: 2

counter2.increment();  // 두 번째 숫자 세기: 1

// 잘못된 생각: counter2도 2가 될 것이라고 생각 ❌
console.log("counter1의 count:", counter1.count);  // 2
console.log("counter2의 count:", counter2.count);  // 1 (독립적이에요!)

각 객체는 독립적인 메모리 공간에 자신만의 속성을 가지고 있어요. 같은 클래스로 만들어졌더라도 서로 다른 존재예요.

❌ 실수 3: 속성을 직접 바꾸는 것과 메서드로 바꾸는 것 혼동

class BankAccount {
    constructor(balance) {
        this.balance = balance;        // 잔액 저장하기
        this.transactions = [];        // 거래내역을 담을 배열 만들기
    }

    // 안전한 입금 메서드
    deposit(amount) {
        if (amount > 0) {                                    // 0보다 큰 금액인지 확인
            this.balance = this.balance + amount;            // 잔액에 돈 더하기
            this.transactions.push(`입금: ${amount}`);        // 거래내역에 기록하기
            console.log(`입금 완료: ${amount}원`);
        }
    }
}

let account = new BankAccount(1000);    // 계좌 만들기 (1000원으로 시작)

// 올바른 방법 - 메서드 사용하기 (안전해요)
account.deposit(500);                               // 입금 메서드 사용
console.log("거래내역:", account.transactions);     // ["입금: 500"]

// 위험한 방법 - 직접 속성 바꾸기 (권장하지 않아요)
account.balance = account.balance + 300;           // 거래내역에 기록되지 않아요!
console.log("거래내역:", account.transactions);     // ["입금: 500"] - 300원 기록 없음!

메서드를 사용하면 검증과 추가 작업(기록, 로그 등)을 함께 할 수 있어서 더 안전하고 체계적이에요.


연습문제 시작 전 잠깐, 이런 생각이 들어요.

각 객체가 자신만의 속성을 가진다는 것, 이게 참 신기하면서도 당연한 일이에요. 우리 각자가 서로 다른 이름과 나이, 취향을 가지고 있는 것처럼요. 코드 속에서도 이런 개별성이 존중받는다는 게, 마치 작은 세상이 따로 돌아가는 것 같아요. 하나가 변해도 다른 하나는 그대로 자기 자리를 지키는 모습이 참 아름답지 않나요?

✏️ 연습문제로 개념 다지기

이제 배운 내용을 연습문제를 통해 확실히 익혀보겠습니다.

Ex1) 애완동물 키우기 - 속성과 메서드를 활용해보자

class Pet {
    constructor(name, species) {
        this.name = name;          // 이름 저장
        this.species = species;    // 동물 종류 저장
        this.hunger = 50;         // 배고픔을 50으로 시작
        this.happiness = 50;      // 행복을 50으로 시작
        this.energy = 100;        // 에너지를 100으로 시작
    }

    // 먹이 주기 메서드
    feed() {
        this.hunger = Math.max(0, this.hunger - 30);           // 배고픔을 30 줄임 (0 아래로 안 내려가게)
        this.happiness = Math.min(100, this.happiness + 10);   // 행복을 10 늘림 (100 위로 안 올라가게)
        console.log(`${this.name}이(가) 맛있게 먹었어요!`);
    }

    // 놀아주기 메서드
    play() {
        this.happiness = Math.min(100, this.happiness + 20);   // 행복을 20 늘림 (100 위로 안 올라가게)
        this.energy = Math.max(0, this.energy - 15);           // 에너지를 15 줄임 (0 아래로 안 내려가게)
        console.log(`${this.name}이(가) 즐겁게 놀았어요!`);
    }
}

// 여러 애완동물을 만들고 각각 다르게 관리해보세요.
let pet1 = new Pet("멍멍이", "강아지");    // 강아지 애완동물 만들기
let pet2 = new Pet("야옹이", "고양이");    // 고양이 애완동물 만들기

pet1.feed();    // 멍멍이에게 먹이 주기
pet2.play();    // 야옹이와 놀아주기

console.log(`${pet1.name} 배고픔: ${pet1.hunger}, 행복: ${pet1.happiness}`);
console.log(`${pet2.name} 배고픔: ${pet2.hunger}, 행복: ${pet2.happiness}`);

Ex2) 속성에 안전하게 접근하는 방법을 비교해보자

class Car {
    constructor(brand, model) {
        this.brand = brand;        // 브랜드 저장
        this.model = model;        // 모델 저장
        this.speed = 0;           // 속도를 0으로 시작
        this.fuel = 100;          // 연료를 100으로 시작
    }

    // 안전한 가속 메서드
    accelerate(amount) {
        if (this.fuel > 0) {                           // 연료가 있는지 확인
            this.speed = Math.min(120, this.speed + amount);  // 속도를 늘림 (최대 120까지)
            this.fuel = Math.max(0, this.fuel - 2);           // 연료를 2 줄임
            console.log(`가속! 현재 속도: ${this.speed}km/h`);
        } else {
            console.log("연료가 부족해요!");
        }
    }
}

let myCar = new Car("현대", "소나타");    // 현대 소나타 만들기

// 안전한 방법 - 메서드 사용하기
myCar.accelerate(30);                     // 가속 메서드 사용하기

// 직접 접근하기 - 주의가 필요해요 (연료 소모 로직이 없어요)
myCar.speed = 80;                         // 속도를 직접 바꾸기
console.log("직접 바꾼 속도:", myCar.speed);

Ex3) 객체의 독립성을 확인해보자

class BankAccount {
    constructor(owner, balance = 0) {
        this.owner = owner;        // 계좌 주인 저장
        this.balance = balance;    // 잔액 저장
    }

    // 돈 넣기 메서드
    deposit(amount) {
        this.balance = this.balance + amount;                // 잔액에 돈을 더함
        console.log(`${this.owner}님 ${amount}원 입금 완료`);
    }
}

// 여러 계좌 만들고 독립성 확인하기
let account1 = new BankAccount("철수", 1000);    // 철수 계좌 만들기 (1000원으로 시작)
let account2 = new BankAccount("영희", 2000);    // 영희 계좌 만들기 (2000원으로 시작)

account1.deposit(500);    // 철수 계좌에 500원 넣기
account2.deposit(300);    // 영희 계좌에 300원 넣기

console.log("철수 잔액:", account1.balance);  // 1500
console.log("영희 잔액:", account2.balance);  // 2300
console.log("같은 계좌인가요?", account1 === account2);  // false - 서로 다른 계좌예요!

🤔 조금 더 어려운 문제로 실력 확인하기

기본 연습을 마쳤다면, 이제 조금 더 깊이 있는 문제들을 통해 인스턴스 속성과 메서드에 대한 이해를 확인해보겠습니다.

Q1. 인스턴스 속성과 메서드의 관계를 설명하고, 왜 메서드에서 this를 사용해야 하는지 말해보세요.

정답: 인스턴스 속성은 각 객체가 가지는 개별 정보이고, 인스턴스 메서드는 그 정보를 다루는 기능입니다. 메서드에서 this를 사용해야 하는 이유는 같은 클래스로 만든 여러 객체 중에서 "현재 이 메서드를 사용한 객체"의 속성에 접근하기 위해서입니다. this 없이는 어떤 객체의 속성을 다뤄야 할지 알 수 없습니다.

Q2. 속성에 직접 접근하는 것과 메서드를 통해 접근하는 것의 차이점을 설명해보세요.

정답: 속성에 직접 접근하는 것은 빠르지만 검증이나 추가 작업이 없어서 위험할 수 있고, 메서드를 통해 접근하면 검증, 기록, 계산 등의 추가 작업이 함께 이루어져서 더 안전하고 체계적입니다. 예를 들어 은행 계좌에서 잔액을 직접 바꾸면 거래 기록이 남지 않지만, 입금 메서드를 사용하면 거래 내역이 자동으로 기록됩니다.

🧚‍♀️ 이야기로 다시 배우기: 학교의 개인 사물함

지금까지 배운 내용을 재미있는 이야기로 다시 정리해볼까요?

어느 학교에는 특별한 사물함 시스템이 있었어요. 모든 학생들이 똑같이 생긴 사물함을 하나씩 받았지만, 각자의 사물함은 완전히 독립적이었답니다.

각 학생의 인스턴스 속성(사물함 내용물):

  • 철수 사물함: 교과서 3권, 필통 1개, 간식 2개, 성적 "우수"
  • 영희 사물함: 교과서 5권, 노트북 1개, 간식 1개, 성적 "매우우수"
  • 민수 사물함: 교과서 1권, 운동화 1개, 간식 3개, 성적 "보통"

각 학생이 할 수 있는 일(인스턴스 메서드):

  • 사물함열기() → 자신의 사물함만 열림
  • 공부하기() → 자신의 성적만 상승
  • 간식먹기() → 자신의 간식만 줄어듦
  • 물건추가() → 자신의 사물함에만 추가

정말 신기한 건 철수가 공부해서 성적이 올라도 영희나 민수의 성적은 전혀 변하지 않았다는 거예요. 각자의 사물함이 잠금장치로 보호되어 있어서 서로 방해할 수 없었거든요.

인스턴스 속성과 메서드도 똑같은 개인 사물함이에요. 각 객체마다 자신만의 정보 저장공간과 기능을 가지고 있어서, 하나의 객체를 바꿔도 다른 객체들에게는 전혀 영향을 주지 않아요.

✅ 학습 완료 체크리스트

이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요!

학습 내용 이해했나요?
인스턴스 속성과 메서드의 개념
this 키워드 사용법
속성 접근 방법의 차이점
자주 하는 실수들
실전 예제 이해
14단원 복습 완료

🎯 추가 연습 문제들

조금 더 연습하고 싶은 친구들을 위한 추가 문제들이에요!

추가 문제 1. 도서관 책 클래스를 만들어보세요.

// 답:
class Book {
    constructor(title, author, pages) {
        this.title = title;
        this.author = author;
        this.pages = pages;
        this.currentPage = 0;
        this.isRead = false;
    }

    // 책 읽기 메서드
    read(pagesToRead) {
        this.currentPage = Math.min(this.pages, this.currentPage + pagesToRead);
        if (this.currentPage >= this.pages) {
            this.isRead = true;
            console.log(`${this.title} 읽기 완료!`);
        } else {
            console.log(`${this.title} ${this.currentPage}/${this.pages} 페이지 읽는 중...`);
        }
    }

    // 진행률 확인 메서드
    getProgress() {
        return (this.currentPage / this.pages * 100).toFixed(1);
    }
}

// 책 만들고 읽어보기
let book1 = new Book("해리포터", "J.K.롤링", 300);
let book2 = new Book("어린왕자", "생텍쥐페리", 100);

book1.read(50);
book2.read(30);

console.log(`${book1.title} 진행률: ${book1.getProgress()}%`);
console.log(`${book2.title} 진행률: ${book2.getProgress()}%`);

추가 문제 2. 온도계 클래스를 만들어보세요.

// 답:
class Thermometer {
    constructor(location) {
        this.location = location;
        this.temperature = 20;  // 기본 온도 20도
        this.unit = "C";        // 섭씨 기본
    }

    // 온도 설정 메서드
    setTemperature(temp) {
        this.temperature = temp;
        console.log(`${this.location}의 온도: ${temp}°${this.unit}`);
    }

    // 화씨로 변환 메서드
    toFahrenheit() {
        if (this.unit === "C") {
            return (this.temperature * 9/5) + 32;
        }
        return this.temperature;
    }

    // 상태 확인 메서드
    getStatus() {
        let status;
        if (this.temperature < 0) status = "얼음";
        else if (this.temperature < 15) status = "추움";
        else if (this.temperature < 25) status = "적당";
        else status = "더움";

        return `${this.location}: ${this.temperature}°${this.unit} (${status})`;
    }
}

// 온도계 만들고 사용하기
let roomThermo = new Thermometer("거실");
let outdoorThermo = new Thermometer("야외");

roomThermo.setTemperature(22);
outdoorThermo.setTemperature(5);

console.log(roomThermo.getStatus());
console.log(outdoorThermo.getStatus());
console.log(`거실 화씨 온도: ${roomThermo.toFahrenheit()}°F`);

📂 마무리 정보

오늘 배운 15.2.2 내용이 여러분의 자바스크립트 지식 상자에 잘 저장되었나요? 다음 시간에는 더 재미있는 내용으로 만나요!

기억할 점: 오늘 배운 내용을 꼭 연습해보시고, 궁금한 점이 있으면 언제든 다시 돌아와서 읽어보세요.


🚀 더 체계적인 JavaScript 학습을 원하신다면?
이 포스팅에서 다룬 내용을 실제로 실습해보세요!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
📝 실시간 코드 실행 📊 학습 진도 관리 👥 체계적 커리큘럼
📚 171개 체계적 학습레슨 · 📋 855개 4지선다 연습문제 · 🆓 완전 무료 · ⚡ 즉시 시작