프론트엔드/JavaScript
클래스
Ryuzy
2025. 4. 13. 20:50
728x90
반응형
1. 클래스
클래스(Class)는 객체지향 프로그래밍에서 객체를 만들기 위한 설계도 또는 틀입니다. 하나의 클래스는 공통된 속성과 동작을 가진 객체들을 정의하며, 이 클래스를 바탕으로 실제 사용할 수 있는 객체(인스턴스)를 생성합니다. 예를 들어, 학생이라는 클래스를 만들면, 이름, 나이 같은 속성과 공부한다는 행동을 포함시킬 수 있고, 이 클래스를 사용해 여러 명의 학생 객체를 만들 수 있습니다. 클래스는 코드의 재사용성, 확장성, 유지보수성을 높여주며, 객체지향 프로그래밍의 핵심 구조로 작동합니다. 자바스크립트에서는 ES6(ECMAScript 2015)부터 class 문법이 도입되었습니다.
class 클래스이름 {
constructor(매개변수들) {
// 객체 초기화 (속성 정의)
}
메서드이름() {
// 객체가 할 수 있는 동작 정의
}
}
2. 클래스 문법 요소
1. constructor()
객체가 생성될 때 자동으로 호출되는 초기화 함수
class Animal {
constructor(type) {
this.type = type;
}
}
const dog = new Animal("강아지");
console.log(dog.type);
2. 인스턴스 메서드 (클래스 내부 함수)
클래스 안에 constructor 외의 함수는 메서드로 등록됩니다.
class Dog {
bark() {
console.log("멍멍!");
}
}
const dog = new Dog();
dog.bark();
3. this 키워드
생성된 객체 자신을 가리킵니다.
class Car {
constructor(name) {
this.name = name; // this → 현재 생성되는 객체
}
start() {
console.log(`${this.name} 시동 켜짐`);
}
}
const myCar = new Car("소나타");
myCar.start();
4. 클래스 상속 (extends)
다른 클래스의 속성과 메서드를 물려받을 수 있음
class Animal {
speak() {
console.log("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
speak() {
console.log("멍멍!");
}
}
const dog = new Dog();
dog.speak();
5. super() — 부모 클래스 constructor 호출
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, color) {
super(name); // Animal의 constructor 호출
this.color = color;
}
showInfo() {
console.log(`${this.name}는 ${this.color} 강아지입니다.`);
}
}
const dog = new Dog("루시", "흰색");
dog.showInfo();
6. 정적 메서드 (static)
클래스 이름으로 직접 호출, 객체로는 호출하지 않음
class MathTool {
static add(a, b) {
return a + b;
}
}
console.log(MathTool.add(3, 4)); // 출력: 7
// MathTool 인스턴스를 만들지 않아도 사용 가능
7. 클래스 필드 (속성) 정의 (ES2022 이후)
코드가 더 간결하고 보기 쉬움 | constructor 없이 속성을 바로 정의 가능 |
변수 선언이 한눈에 보임 | 어떤 속성이 있는지 클래스 맨 위에서 확인 가능 |
static, private과 함께 쓰기 쉬움 | 클래스 레벨 속성, 비공개 속성 정의에 유리함 |
class Product {
name = "상품명 없음";
price = 0;
showInfo() {
console.log(`${this.name}의 가격은 ${this.price}원입니다.`);
}
}
const p = new Product();
p.showInfo();
8. get과 set
자바스크립트에서는 get과 set 키워드를 사용해서 객체 속성에 접근하거나 값을 설정할 때 특별한 동작을 지정할 수 있습니다. 이를 통해 속성처럼 보이지만, 실제로는 함수처럼 작동하는 코드를 만들 수 있습니다.
- get과 set은 같은 이름을 공유해야 합니다 (name)
- 내부에서 값을 저장할 땐 보통 _name처럼 언더스코어를 붙여서 구분합니다 (충돌 방지)
- get만 정의하면 읽기 전용 속성이 됩니다 (쓰기 불가)
class User {
constructor(name) {
this._name = name; // 실제 값은 밑줄(_)로 저장
}
// getter
get name() {
return this._name;
}
// setter
set name(newName) {
if (newName.length < 2) {
console.log("이름은 두 글자 이상이어야 합니다.");
} else {
this._name = newName;
}
}
}
const user = new User("김사과");
console.log(user.name);
user.name = "반";
user.name = "반하나";
console.log(user.name);
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
get area() {
return this.width * this.height;
}
}
const rect = new Rectangle(5, 4);
console.log(rect.area);
9. private 필드
클래스 내부에서만 접근 가능한 비공개 속성(변수)입니다. 외부에서 직접 접근하거나 수정할 수 없고, 클래스 안에서만 사용 가능합니다.
- #을 붙이면 반드시 동일한 클래스 안에서만 접근 가능
- this.#속성명으로만 접근 가능하며, 다른 객체에서 객체.#속성처럼 쓰면 에러 발생
class User {
#password = "";
constructor(userid, password) {
this.userid = userid;
this.#password = password;
}
checkPassword(input) {
return this.#password === input;
}
}
const user = new User("apple", "1111");
console.log(user.userid);
console.log(user.checkPassword("1111"));
console.log(user.checkPassword("wrong"));
console.log(user.#password); // Private field '#password' must be declared in an enclosing class
class Account {
// static 필드: 모든 계좌에서 공유됨
static accountCount = 0;
// private 필드: 외부에서 접근 불가
#balance = 0;
constructor(owner) {
this.owner = owner;
Account.accountCount++; // 생성될 때마다 1 증가
}
// getter: 외부에서 잔액을 읽을 수 있게
get balance() {
return this.#balance;
}
// setter: 잔액을 직접 설정할 수 없도록 차단
set balance(value) {
console.log("직접 잔액을 설정할 수 없습니다.");
}
// 입금
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
console.log(`${this.owner}님, ${amount}원 입금되었습니다.`);
}
}
// 출금
withdraw(amount) {
if (amount <= this.#balance) {
this.#balance -= amount;
console.log(`${this.owner}님, ${amount}원 출금되었습니다.`);
} else {
console.log("잔액이 부족합니다.");
}
}
// static 메서드: 클래스 자체에서 호출
static getAccountCount() {
return `총 계좌 수: ${Account.accountCount}`;
}
}
const a1 = new Account("김사과");
a1.deposit(1000);
console.log(a1.balance); // getter → 1000
a1.balance = 5000; // setter 차단 메시지
console.log(a1.balance); // 여전히 1000
a1.withdraw(300); // 300 출금됨
const a2 = new Account("반하나");
a2.deposit(2000);
// static 메서드는 클래스명으로 호출
console.log(Account.getAccountCount()); // 출력: 총 계좌 수: 2
3. 객체지향의 4대 핵심 개념
1. 캡슐화 (Encapsulation)
관련된 데이터(속성)와 동작(메서드)을 하나의 객체로 묶는 것
class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
introduce() {
console.log(`안녕하세요, 저는 ${this.name}입니다.`);
}
}
const u = new User("김사과", 20);
u.introduce();
2. 은닉성 (Information Hiding)
객체의 내부 정보를 외부에서 직접 접근하지 못하도록 감추는 것
class Account {
#balance = 0; // private 필드
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
getBalance() {
return this.#balance;
}
}
const acc = new Account();
acc.deposit(1000);
console.log(acc.getBalance()); // 출력: 1000
console.log(acc.#balance); // 오류: private 필드 접근 불가
3. 상속 (Inheritance)
기존 클래스의 기능을 물려받아 새로운 클래스를 만드는 것
class Animal {
speak() {
console.log("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
speak() {
console.log("멍멍!");
}
}
const dog = new Dog();
dog.speak();
4. 다형성 (Polymorphism)
같은 이름의 메서드가 상황에 따라 다르게 동작하는 것
class Animal {
speak() {
console.log("동물이 소리를 냅니다.");
}
}
class Cat extends Animal {
speak() {
console.log("야옹~");
}
}
class Dog extends Animal {
speak() {
console.log("멍멍!");
}
}
const animals = [new Cat(), new Dog()];
for (let a of animals) {
a.speak();
}
728x90
반응형