๐ ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค ์์ฑ๋ฒ ๋ง์คํฐํ๊ธฐ ๐

์๋ ํ์ธ์, ์ฌ๋ฌ๋ถ! ์ค๋์ ํ์ ์คํฌ๋ฆฝํธ์ ๊ฝ์ด๋ผ๊ณ ํ ์ ์๋ ํด๋์ค ์์ฑ๋ฒ์ ๋ํด ๊น์ด ์๊ฒ ํํค์ณ๋ณผ ๊ฑฐ์์. ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค๋ฅผ ๋ง์คํฐํ๋ฉด ์ฌ๋ฌ๋ถ์ ์ฝ๋ฉ ์ค๋ ฅ์ด ํ ๋จ๊ณ ์ ๊ทธ๋ ์ด๋๋ ๊ฑฐ๋ผ๊ณ ์ฅ๋ดํ ์ ์์ด์! ๐
ํ์ ์คํฌ๋ฆฝํธ๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ์ํผ์ ์ผ๋ก, ์ ์ ํ์ ์ ์ง์ํ๋ ๊ฐ๋ ฅํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์. ํนํ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ฅ์ ์ ์ต๋ํ ํ์ฉํ ์ ์์ฃ . ๊ทธ๋ผ ์ด์ ๋ถํฐ ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์ ์ธ๊ณ๋ก ๋น ์ ธ๋ณผ๊น์? ๐โโ๏ธ
๐ก Pro Tip: ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค๋ฅผ ๋ง์คํฐํ๋ฉด ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ํฌ๊ฒ ํฅ์๋ผ์. ์ด๋ ๋๊ท๋ชจ ํ๋ก์ ํธ์์ ํนํ ์ค์ํ๋ต๋๋ค!
์, ๊ทธ๋ผ ๋ณธ๊ฒฉ์ ์ผ๋ก ์์ํด๋ณผ๊น์? ์ค๋น๋์ จ๋์? ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์ ์ธ๊ณ๋ก Go Go! ๐๐จ
1. ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์ ๊ธฐ๋ณธ ๊ตฌ์กฐ ๐๏ธ
ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ถํฐ ์ดํด๋ณผ๊ฒ์. ํด๋์ค๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํ ํ ํ๋ฆฟ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ผ์. ๋ง์น ์ฟ ํค ํ์ฒ๋ผ์! ๐ช
class Cookie {
flavor: string;
constructor(flavor: string) {
this.flavor = flavor;
}
describe(): string {
return `This is a ${this.flavor} flavored cookie.`;
}
}
const chocolateCookie = new Cookie('chocolate');
console.log(chocolateCookie.describe()); // "This is a chocolate flavored cookie."
์ด ์์ ์์ ์ฐ๋ฆฌ๋ 'Cookie'๋ผ๋ ํด๋์ค๋ฅผ ๋ง๋ค์์ด์. ์ด ํด๋์ค๋ 'flavor'๋ผ๋ ์์ฑ๊ณผ 'describe'๋ผ๋ ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์์ฃ . 'constructor'๋ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ ํธ์ถ๋๋ ํน๋ณํ ๋ฉ์๋์์.
ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋น์ทํ ํน์ฑ์ ๊ฐ์ง ๊ฐ์ฒด๋ค์ ์ฝ๊ฒ ๋ง๋ค ์ ์์ด์. ์๋ฅผ ๋ค์ด, ๋ค์ํ ๋ง์ ์ฟ ํค๋ฅผ ๋ง๋ค ์ ์๊ฒ ์ฃ ?
const strawberryCookie = new Cookie('strawberry');
const vanillaCookie = new Cookie('vanilla');
console.log(strawberryCookie.describe()); // "This is a strawberry flavored cookie."
console.log(vanillaCookie.describe()); // "This is a vanilla flavored cookie."
์ด๋ ๊ฒ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ด ๋์์ง๊ณ , ๊ตฌ์กฐํ๋ ํ๋ก๊ทธ๋๋ฐ์ด ๊ฐ๋ฅํด์ ธ์. ๋ง์น ์ฌ๋ฅ๋ท์์ ๋ค์ํ ์ฌ๋ฅ์ ์ฒด๊ณ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ฒ๋ผ ๋ง์ด์์! ๐
๐ฌ Sweet Tip: ํด๋์ค ์ด๋ฆ์ ํญ์ ๋๋ฌธ์๋ก ์์ํ๋ ๊ฒ์ด ๊ด๋ก์์. 'cookie'๊ฐ ์๋๋ผ 'Cookie'์ฒ๋ผ์!
์, ์ด์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ์์์ผ๋ ๋ ๊น์ด ๋ค์ด๊ฐ๋ณผ๊น์? ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์ ๋ค์ํ ํน์ฑ๋ค์ ํ๋์ฉ ์ดํด๋ณด๊ฒ ์ต๋๋ค! ๐ต๏ธโโ๏ธ
2. ์ ๊ทผ ์ ์ด์ (Access Modifiers) ๐
ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์์๋ ๋ฉค๋ฒ(์์ฑ๊ณผ ๋ฉ์๋)์ ์ ๊ทผ์ฑ์ ์ ์ดํ ์ ์์ด์. ์ด๋ฅผ ์ํด ์ธ ๊ฐ์ง ์ ๊ทผ ์ ์ด์๋ฅผ ์ฌ์ฉํ ์ ์์ฃ . ๋ฐ๋ก public, private, protected์์.
- public: ๊ธฐ๋ณธ๊ฐ์ด์์. ํด๋์ค ์ธ๋ถ์์ ์์ ๋กญ๊ฒ ์ ๊ทผ ๊ฐ๋ฅํด์.
- private: ํด๋น ํด๋์ค ๋ด๋ถ์์๋ง ์ ๊ทผ ๊ฐ๋ฅํด์.
- protected: ํด๋น ํด๋์ค์ ์์๋ฐ์ ์์ ํด๋์ค์์๋ง ์ ๊ทผ ๊ฐ๋ฅํด์.
์์ ๋ฅผ ํตํด ์ดํด๋ณผ๊น์?
class BankAccount {
public accountHolder: string;
private balance: number;
protected accountNumber: string;
constructor(accountHolder: string, initialBalance: number) {
this.accountHolder = accountHolder;
this.balance = initialBalance;
this.accountNumber = Math.random().toString(36).substr(2, 9);
}
public deposit(amount: number): void {
this.balance += amount;
}
public withdraw(amount: number): boolean {
if (this.balance >= amount) {
this.balance -= amount;
return true;
}
return false;
}
private calculateInterest(): number {
return this.balance * 0.05;
}
protected getAccountDetails(): string {
return `Account Number: ${this.accountNumber}, Balance: ${this.balance}`;
}
}
const myAccount = new BankAccount('ํ๊ธธ๋', 1000000);
console.log(myAccount.accountHolder); // 'ํ๊ธธ๋'
myAccount.deposit(500000);
console.log(myAccount.withdraw(200000)); // true
// ์๋ ์ฝ๋๋ค์ ์ปดํ์ผ ์๋ฌ๋ฅผ ๋ฐ์์ํต๋๋ค.
// console.log(myAccount.balance); // Error: Property 'balance' is private and only accessible within class 'BankAccount'.
// console.log(myAccount.calculateInterest()); // Error: Property 'calculateInterest' is private and only accessible within class 'BankAccount'.
// console.log(myAccount.getAccountDetails()); // Error: Property 'getAccountDetails' is protected and only accessible within class 'BankAccount' and its subclasses.
์ด ์์ ์์ 'BankAccount' ํด๋์ค๋ ๋ค์ํ ์ ๊ทผ ์ ์ด์๋ฅผ ์ฌ์ฉํ๊ณ ์์ด์. 'accountHolder'๋ public์ด๋ผ ์ธ๋ถ์์ ์์ ๋กญ๊ฒ ์ ๊ทผํ ์ ์์ง๋ง, 'balance'๋ private์ด๋ผ ํด๋์ค ๋ด๋ถ์์๋ง ์ ๊ทผ ๊ฐ๋ฅํด์. 'accountNumber'๋ protected๋ผ์ ์ด ํด๋์ค์ ์์๋ฐ์ ํด๋์ค์์๋ง ์ ๊ทผํ ์ ์์ฃ .
๐ฐ Money Tip: ์ค์ ์ํ ์์คํ ์ฒ๋ผ, ์ค์ํ ์ ๋ณด๋ private์ผ๋ก ์ค์ ํ๊ณ , ํ์ํ ๊ธฐ๋ฅ๋ง public์ผ๋ก ์ ๊ณตํ๋ ๊ฒ์ด ์ข์์. ์ด๋ ๊ฒ ํ๋ฉด ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ์งํฌ ์ ์๋ต๋๋ค!
์ ๊ทผ ์ ์ด์๋ฅผ ์ ํ์ฉํ๋ฉด ํด๋์ค์ ๋ด๋ถ ๊ตฌํ์ ์จ๊ธฐ๊ณ ํ์ํ ์ธํฐํ์ด์ค๋ง ์ธ๋ถ์ ๋ ธ์ถ์ํฌ ์ ์์ด์. ์ด๋ฅผ ํตํด ์ฝ๋์ ์์ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ผ ์ ์์ฃ . ๋ง์น ์ฌ๋ฅ๋ท์์ ์ฌ์ฉ์์ ๊ฐ์ธ์ ๋ณด๋ฅผ ์์ ํ๊ฒ ๋ณดํธํ๋ ๊ฒ์ฒ๋ผ ๋ง์ด์์! ๐
์, ์ด์ ์ ๊ทผ ์ ์ด์์ ๋ํด ์์์ผ๋, ๋ค์์ผ๋ก ๋์ด๊ฐ๋ณผ๊น์? ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์ ๋ ๋ค๋ฅธ ์ค์ํ ํน์ฑ์ธ ์์์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค! ๐งฌ
3. ํด๋์ค ์์ (Inheritance) ๐จโ๐ฉโ๐งโ๐ฆ
์์์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ํต์ฌ ๊ฐ๋ ์ค ํ๋์์. ๊ธฐ์กด ํด๋์ค์ ํน์ฑ์ ์๋ก์ด ํด๋์ค๊ฐ ๋ฌผ๋ ค๋ฐ์ ์ ์๊ฒ ํด์ฃผ์ฃ . ์ด๋ฅผ ํตํด ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ณ , ๊ตฌ์กฐ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๋ง๋ค ์ ์์ด์.
ํ์ ์คํฌ๋ฆฝํธ์์๋ 'extends' ํค์๋๋ฅผ ์ฌ์ฉํด ํด๋์ค๋ฅผ ์์๋ฐ์ ์ ์์ด์. ํ๋ฒ ์์ ๋ฅผ ํตํด ์ดํด๋ณผ๊น์?
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log("Some generic animal sound");
}
}
class Dog extends Animal {
breed: string;
constructor(name: string, breed: string) {
super(name); // ๋ถ๋ชจ ํด๋์ค์ constructor๋ฅผ ํธ์ถ
this.breed = breed;
}
makeSound(): void {
console.log("Woof! Woof!");
}
fetch(): void {
console.log(`${this.name} is fetching the ball!`);
}
}
const myDog = new Dog("๋ฝ์", "ํธ๋ค");
console.log(myDog.name); // "๋ฝ์"
console.log(myDog.breed); // "ํธ๋ค"
myDog.makeSound(); // "Woof! Woof!"
myDog.fetch(); // "๋ฝ์ is fetching the ball!"
์ด ์์ ์์ 'Dog' ํด๋์ค๋ 'Animal' ํด๋์ค๋ฅผ ์์๋ฐ๊ณ ์์ด์. 'Dog' ํด๋์ค๋ 'Animal' ํด๋์ค์ ๋ชจ๋ ํน์ฑ(์ฌ๊ธฐ์๋ 'name' ์์ฑ๊ณผ 'makeSound' ๋ฉ์๋)์ ๊ฐ์ง๋ฉด์, ์์ ๋ง์ ํน์ฑ('breed' ์์ฑ๊ณผ 'fetch' ๋ฉ์๋)๋ ์ถ๊ฐํ ์ ์์ฃ .
'super' ํค์๋๋ ๋ถ๋ชจ ํด๋์ค์ constructor๋ฅผ ํธ์ถํ๋ ๋ฐ ์ฌ์ฉ๋ผ์. ์ด๋ฅผ ํตํด ๋ถ๋ชจ ํด๋์ค์์ ์ ์๋ ์ด๊ธฐํ ๋ก์ง์ ์ฌ์ฌ์ฉํ ์ ์์ฃ .
๋ํ, 'Dog' ํด๋์ค์์ 'makeSound' ๋ฉ์๋๋ฅผ ์๋ก ์ ์ํ๋๋ฐ, ์ด๋ฅผ ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ(method overriding)์ด๋ผ๊ณ ํด์. ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋๋ฅผ ์์ ํด๋์ค์์ ์ฌ์ ์ํ๋ ๊ฑฐ์ฃ .
๐พ Paw Tip: ์์์ ์ฌ์ฉํ ๋๋ "is-a" ๊ด๊ณ๋ฅผ ๊ณ ๋ คํด๋ณด์ธ์. "๊ฐ๋ ๋๋ฌผ์ด๋ค(A dog is an animal)"๋ผ๋ ๊ด๊ณ๊ฐ ์ฑ๋ฆฝํ๋ฏ๋ก ์ด ๊ฒฝ์ฐ ์์์ด ์ ์ ํด์!
์์์ ํ์ฉํ๋ฉด ์ฝ๋์ ์ค๋ณต์ ์ค์ด๊ณ , ๊ตฌ์กฐ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๋ง๋ค ์ ์์ด์. ์๋ฅผ ๋ค์ด, ์ฌ๋ฅ๋ท์์ ๋ค์ํ ์ ํ์ ์ฌ์ฉ์(์ผ๋ฐ ์ฌ์ฉ์, ํ๋ฆฌ๋ฏธ์ ์ฌ์ฉ์, ๊ด๋ฆฌ์ ๋ฑ)๋ฅผ ๊ตฌํํ ๋ ์์์ ํ์ฉํ๋ฉด ํจ์จ์ ์ผ๋ก ์ฝ๋๋ฅผ ๊ด๋ฆฌํ ์ ์์ ๊ฑฐ์์! ๐จโ๐ผ๐ฉโ๐ผ
์, ์ด์ ์์์ ๋ํด ์์๋ดค์ผ๋, ๋ค์์ผ๋ก ์ธํฐํ์ด์ค์ ๋ํด ์์๋ณผ๊น์? ์ธํฐํ์ด์ค๋ ํ์ ์คํฌ๋ฆฝํธ์์ ๋งค์ฐ ์ค์ํ ๊ฐ๋ ์ด์์. ํจ๊ป ์ดํด๋ณด์ฃ ! ๐ง
4. ์ธํฐํ์ด์ค (Interface) ๐ค
์ธํฐํ์ด์ค๋ ํ์ ์คํฌ๋ฆฝํธ์ ํต์ฌ ๊ธฐ๋ฅ ์ค ํ๋์์. ์ธํฐํ์ด์ค๋ฅผ ํตํด ๊ฐ์ฒด์ ๊ตฌ์กฐ๋ฅผ ์ ์ํ ์ ์์ฃ . ํด๋์ค๊ฐ ํน์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฅด๋๋ก ๊ฐ์ ํ ์๋ ์๊ณ , ํจ์์ ๋งค๊ฐ๋ณ์๋ ๋ฐํ๊ฐ์ ํ์ ์ ์ง์ ํ ๋๋ ์ฌ์ฉํ ์ ์์ด์.
์ธํฐํ์ด์ค์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ๋ถํฐ ์ดํด๋ณผ๊น์?
interface Person {
name: string;
age: number;
greet(): void;
}
class Student implements Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): void {
console.log(`์๋
ํ์ธ์, ์ ๋ ${this.name}์ด๊ณ ${this.age}์ด์
๋๋ค.`);
}
study(): void {
console.log(`${this.name}์ด(๊ฐ) ๊ณต๋ถ ์ค์
๋๋ค.`);
}
}
const student1 = new Student("๊น์ฒ ์", 20);
student1.greet(); // "์๋
ํ์ธ์, ์ ๋ ๊น์ฒ ์์ด๊ณ 20์ด์
๋๋ค."
student1.study(); // "๊น์ฒ ์์ด(๊ฐ) ๊ณต๋ถ ์ค์
๋๋ค."
์ด ์์ ์์ 'Person' ์ธํฐํ์ด์ค๋ 'name'๊ณผ 'age' ์์ฑ, ๊ทธ๋ฆฌ๊ณ 'greet' ๋ฉ์๋๋ฅผ ๊ฐ์ ธ์ผ ํ๋ค๊ณ ์ ์ํ๊ณ ์์ด์. 'Student' ํด๋์ค๋ ์ด ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํ(implement)ํ๊ณ ์์ฃ .
'implements' ํค์๋๋ฅผ ์ฌ์ฉํด ํด๋์ค๊ฐ ํน์ ์ธํฐํ์ด์ค๋ฅผ ๋ฐ๋ฅด๋๋ก ํ ์ ์์ด์. ์ด๋ ๊ฒ ํ๋ฉด ํด๋น ํด๋์ค๋ ๋ฐ๋์ ์ธํฐํ์ด์ค์ ์ ์๋ ๋ชจ๋ ์์ฑ๊ณผ ๋ฉ์๋๋ฅผ ๊ตฌํํด์ผ ํด์. ๊ตฌํํ์ง ์์ผ๋ฉด ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํ์ฃ .
์ธํฐํ์ด์ค๋ ์ฌ๋ฌ ๊ฐ๋ฅผ ๋์์ ๊ตฌํํ ์๋ ์์ด์. ์๋ฅผ ๋ค์ด๋ณผ๊น์?
interface Printable {
print(): void;
}
class Book implements Person, Printable {
name: string;
age: number;
author: string;
constructor(name: string, age: number, author: string) {
this.name = name;
this.age = age;
this.author = author;
}
greet(): void {
console.log(`์ด ์ฑ
์ ์ ๋ชฉ์ ${this.name}์ด๊ณ , ์ถ๊ฐ๋ ์ง ${this.age}๋
๋์์ต๋๋ค.`);
}
print(): void {
console.log(`${this.name} by ${this.author}`);
}
}
const myBook = new Book("TypeScript ๋ง์คํฐํ๊ธฐ", 2, "๊น๊ฐ๋ฐ");
myBook.greet(); // "์ด ์ฑ
์ ์ ๋ชฉ์ TypeScript ๋ง์คํฐํ๊ธฐ์ด๊ณ , ์ถ๊ฐ๋ ์ง 2๋
๋์์ต๋๋ค."
myBook.print(); // "TypeScript ๋ง์คํฐํ๊ธฐ by ๊น๊ฐ๋ฐ"
์ฌ๊ธฐ์ 'Book' ํด๋์ค๋ 'Person'๊ณผ 'Printable' ๋ ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ๋์์ ๊ตฌํํ๊ณ ์์ด์. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ๋ฌ ์ธํฐํ์ด์ค์ ํน์ฑ์ ํ ํด๋์ค์ ์กฐํฉํ ์ ์์ฃ .
๐ Book Tip: ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋์ ๊ตฌ์กฐ๋ฅผ ๋ช ํํ ํ๊ณ , ํ์ ์์ ์ฑ์ ๋์ผ ์ ์์ด์. ํนํ ํฐ ํ๋ก์ ํธ์์ ์ฌ๋ฌ ๊ฐ๋ฐ์๊ฐ ํ์ ํ ๋ ๋งค์ฐ ์ ์ฉํ๋ต๋๋ค!
์ธํฐํ์ด์ค๋ ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์ ๊ฐ๋ฐํ ๋ ํนํ ์ ์ฉํ ๊ฑฐ์์. ์๋ฅผ ๋ค์ด, ๋ค์ํ ์ ํ์ ์ฌ๋ฅ(์์ , ๋ฏธ์ , ํ๋ก๊ทธ๋๋ฐ ๋ฑ)์ ํํํ๋ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค๊ณ , ๊ฐ ์ฌ๋ฅ ์ ํ๋ณ๋ก ํด๋์ค๋ฅผ ๊ตฌํํ ์ ์๊ฒ ์ฃ ? ์ด๋ ๊ฒ ํ๋ฉด ์ฝ๋์ ๊ตฌ์กฐ๊ฐ ๋ช ํํด์ง๊ณ , ์๋ก์ด ์ฌ๋ฅ ์ ํ์ ์ถ๊ฐํ๊ธฐ๋ ์ฌ์์ง ๊ฑฐ์์! ๐จ๐ต๐ป
์, ์ด์ ์ธํฐํ์ด์ค์ ๋ํด ์์๋ดค์ผ๋, ๋ค์์ผ๋ก ์ ๋ค๋ฆญ์ ๋ํด ์์๋ณผ๊น์? ์ ๋ค๋ฆญ์ ํ์ ์คํฌ๋ฆฝํธ์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ ์ค ํ๋์์. ํจ๊ป ์ดํด๋ณด์ฃ ! ๐
5. ์ ๋ค๋ฆญ (Generics) ๐งฌ
์ ๋ค๋ฆญ์ ํ์ ์คํฌ๋ฆฝํธ์ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ ์ค ํ๋์์. ์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ํ์ ์์ ์๋ํ ์ ์๋ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค ์ ์์ฃ . ์ฆ, ํ์ ์ ๋ง์น ํจ์์ ๋งค๊ฐ๋ณ์์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ ๊ฑฐ์์.
์ ๋ค๋ฆญ์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ๋ถํฐ ์ดํด๋ณผ๊น์?
class Box<T> {
private content: T;
constructor(content: T) {
this.content = content;
}
getContent(): T {
return this.content;
}
}
const numberBox = new Box<number>(42);
console.log(numberBox.getContent()); // 42
const stringBox = new Box<string>("Hello, TypeScript!");
console.log(stringBox.getContent()); // "Hello, TypeScript!"
์ด ์์ ์์ 'Box' ํด๋์ค๋ ์ ๋ค๋ฆญ ํ์ 'T'๋ฅผ ์ฌ์ฉํ๊ณ ์์ด์. ์ด ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ ์ค์ ํ์ ์ ์ง์ ํ ์ ์์ฃ . 'numberBox'๋ ์ซ์๋ฅผ, 'stringBox'๋ ๋ฌธ์์ด์ ๋ด๊ณ ์์ด์.
์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ฉด ํ์ ์์ ์ฑ์ ์ ์งํ๋ฉด์๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค ์ ์์ด์. ์ปดํ์ผ ์์ ์ ํ์ ์ฒดํฌ๊ฐ ์ด๋ฃจ์ด์ง๊ธฐ ๋๋ฌธ์, ๋ฐํ์ ์๋ฌ๋ฅผ ์ค์ผ ์ ์์ฃ .
์ ๋ค๋ฆญ์ ํด๋์ค๋ฟ๋ง ์๋๋ผ ํจ์์์๋ ์ฌ์ฉํ ์ ์์ด์. ์๋ฅผ ๋ค์ด๋ณผ๊น์?
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}
const result1 = swap<string, number>(["hello", 42]);
console.log(result1); // [42, "hello"]
const result2 = swap(["TypeScript", true]); // ํ์
์ถ๋ก ์ผ๋ก ์ธํด ์ ๋ค๋ฆญ ํ์
์ ๋ช
์์ ์ผ๋ก ์ง์ ํ์ง ์์๋ ๋ผ์
console.log(result2); // [true, "TypeScript"]
์ด 'swap' ํจ์๋ ๋ ๊ฐ์ ์ ๋ค๋ฆญ ํ์ 'T'์ 'U'๋ฅผ ์ฌ์ฉํด์. ์ด ํจ์๋ ํํ์ ๋ ์์์ ์์น๋ฅผ ๋ฐ๊ฟ์ฃผ๋ ์ญํ ์ ํ์ฃ .
์ ๋ค๋ฆญ์ ์ธํฐํ์ด์ค์์๋ ์ฌ์ฉํ ์ ์์ด์. ์ฌ๋ฅ๋ท์ ์๋ฅผ ๋ค์ด๋ณผ๊น์?
interface Talent<T> {
name: string;
description: string;
level: number;
details: T;
}
interface MusicTalentDetails {
instrument: string;
genre: string;
}
interface ProgrammingTalentDetails {
language: string;
yearsOfExperience: number;
}
const musicTalent: Talent<MusicTalentDetails> = {
name: "๊ธฐํ ์ฐ์ฃผ",
description: "๋ฝ๋ถํฐ ์ฌ์ฆ๊น์ง ๋ค์ํ ์ฅ๋ฅด์ ๊ธฐํ ์ฐ์ฃผ",
level: 8,
details: {
instrument: "๊ธฐํ",
genre: "๋ฝ/์ฌ์ฆ"
}
};
const programmingTalent: Talent<ProgrammingTalentDetails> = {
name: "์น ๊ฐ๋ฐ",
description: "ํ๋ก ํธ์๋๋ถํฐ ๋ฐฑ์๋๊น์ง ํ์คํ ์น ๊ฐ๋ฐ",
level: 9,
details: {
language: "TypeScript",
yearsOfExperience: 5
}
};
console.log(musicTalent);
console.log(programmingTalent);
์ด ์์ ์์๋ 'Talent' ์ธํฐํ์ด์ค๊ฐ ์ ๋ค๋ฆญ ํ์ 'T'๋ฅผ ์ฌ์ฉํด์. ์ด๋ฅผ ํตํด ๋ค์ํ ์ข ๋ฅ์ ์ฌ๋ฅ์ ๋ํ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ ์ฐํ๊ฒ ํํํ ์ ์์ฃ . ์์ ์ฌ๋ฅ๊ณผ ํ๋ก๊ทธ๋๋ฐ ์ฌ๋ฅ์ ์๋ก ๋ค๋ฅธ ์ธ๋ถ ์ ๋ณด๋ฅผ ๊ฐ์ง์ง๋ง, ๊ฐ์ 'Talent' ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ ์ ์์ด์.
๐ง Brain Teaser: ์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ฉด ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ด ๋์์ง๊ณ , ํ์ ์์ ์ฑ๋ ์ ์งํ ์ ์์ด์. ํ์ง๋ง ๋๋ฌด ๋ง์ ์ ๋ค๋ฆญ ํ์ ์ ์ฌ์ฉํ๋ฉด ์ฝ๋๊ฐ ๋ณต์กํด์ง ์ ์์ผ๋ ์ฃผ์ํด์ผ ํด์!
์ ๋ค๋ฆญ์ ์ ํ์ฉํ๋ฉด ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ ๋ค์ํ ์ข ๋ฅ์ ์ฌ๋ฅ์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ ๊ฑฐ์์. ๊ฐ ์ฌ๋ฅ ์ ํ๋ณ๋ก ๋ค๋ฅธ ์ธ๋ถ ์ ๋ณด๋ฅผ ๊ฐ์ง ์ ์์ง๋ง, ๋์ผํ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด ์ผ๊ด์ฑ ์๊ฒ ์ฒ๋ฆฌํ ์ ์์ฃ . ์ด๋ ๊ฒ ํ๋ฉด ์๋ก์ด ์ฌ๋ฅ ์ ํ์ ์ถ๊ฐํ๊ธฐ๋ ์ฌ์์ง ๊ฑฐ์์! ๐ญ๐๏ธโโ๏ธ๐จ
์, ์ด์ ์ ๋ค๋ฆญ์ ๋ํด ์์๋ดค์ผ๋, ๋ค์์ผ๋ก ๋ฐ์ฝ๋ ์ดํฐ์ ๋ํด ์์๋ณผ๊น์? ๋ฐ์ฝ๋ ์ดํฐ๋ ํ์ ์คํฌ๋ฆฝํธ์ ์คํ์ ๊ธฐ๋ฅ์ด์ง๋ง, ๋งค์ฐ ์ ์ฉํ๋ต๋๋ค. ํจ๊ป ์ดํด๋ณด์ฃ ! ๐
6. ๋ฐ์ฝ๋ ์ดํฐ (Decorators) ๐
๋ฐ์ฝ๋ ์ดํฐ๋ ํด๋์ค ์ ์ธ, ๋ฉ์๋, ์ ๊ทผ์, ํ๋กํผํฐ ๋๋ ๋งค๊ฐ๋ณ์์ ์ฒจ๋ถํ ์ ์๋ ํน๋ณํ ์ข ๋ฅ์ ์ ์ธ์ด์์. ๋ฐ์ฝ๋ ์ดํฐ๋ '@' ๊ธฐํธ๋ฅผ ์ฌ์ฉํ์ฌ ํํํ๋ฉฐ, ํจ์์ฒ๋ผ ํ๊ฐ๋ผ์.
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด tsconfig.json ํ์ผ์์ "experimentalDecorators" ์ต์ ์ ํ์ฑํํด์ผ ํด์.
{
"compilerOptions": { ๋ค, ๊ณ์ํด์ ๋ฐ์ฝ๋ ์ดํฐ์ ๋ํด ์ค๋ช
๋๋ฆฌ๊ฒ ์ต๋๋ค.
<pre><code>
{
"compilerOptions": {
"experimentalDecorators": true
}
}
์ด์ ๋ฐ์ฝ๋ ์ดํฐ์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ์ ์ดํด๋ณผ๊น์?
function logged(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyKey} with`, args);
const result = originalMethod.apply(this, args);
console.log(`${propertyKey} returned`, result);
return result;
};
return descriptor;
}
class Calculator {
@logged
add(a: number, b: number): number {
return a + b;
}
}
const calc = new Calculator();
calc.add(5, 3);
// ์ถ๋ ฅ:
// Calling add with [5, 3]
// add returned 8
์ด ์์ ์์ '@logged' ๋ฐ์ฝ๋ ์ดํฐ๋ ๋ฉ์๋๊ฐ ํธ์ถ๋ ๋์ ๋ฐํ๋ ๋ ๋ก๊ทธ๋ฅผ ์ถ๋ ฅํด์. ์ด๋ฐ ๋ฐฉ์์ผ๋ก ์ฝ๋์ ๋์์ ์์ ํ๊ฑฐ๋ ํ์ฅํ ์ ์์ฃ .
๋ฐ์ฝ๋ ์ดํฐ๋ ๋ค์ํ ์ฉ๋๋ก ์ฌ์ฉ๋ ์ ์์ด์. ์๋ฅผ ๋ค์ด, ํด๋์ค ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํด ํด๋์ค์ ์๋ก์ด ์์ฑ์ด๋ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ ์ ์์ฃ .
function reportableClass(constructor: Function) {
constructor.prototype.reportingURL = "http://www.example.com/report";
}
@reportableClass
class BugReport {
type = "report";
title: string;
constructor(t: string) {
this.title = t;
}
}
const bug = new BugReport("Needs dark mode");
console.log((bug as any).reportingURL); // "http://www.example.com/report"
์ด ์์ ์์ '@reportableClass' ๋ฐ์ฝ๋ ์ดํฐ๋ 'BugReport' ํด๋์ค์ 'reportingURL' ์์ฑ์ ์ถ๊ฐํด์.
์ฌ๋ฅ๋ท ํ๋ซํผ์์ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํ์ฉํ๋ ์๋ฅผ ๋ค์ด๋ณผ๊น์?
function validateSkillLevel(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
const level = args[0];
if (level < 1 || level > 10) {
throw new Error("Skill level must be between 1 and 10");
}
return originalMethod.apply(this, args);
};
return descriptor;
}
class Talent {
name: string;
level: number;
constructor(name: string) {
this.name = name;
this.level = 1;
}
@validateSkillLevel
setSkillLevel(level: number) {
this.level = level;
console.log(`${this.name} skill level set to ${this.level}`);
}
}
const coding = new Talent("Coding");
coding.setSkillLevel(7); // "Coding skill level set to 7"
// coding.setSkillLevel(11); // Error: Skill level must be between 1 and 10
์ด ์์ ์์ '@validateSkillLevel' ๋ฐ์ฝ๋ ์ดํฐ๋ ์คํฌ ๋ ๋ฒจ์ด ์ ํจํ ๋ฒ์ ๋ด์ ์๋์ง ๊ฒ์ฆํด์. ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ ์ ์์ฃ .
๐ Decorator Tip: ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ณ , ๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌํ ์ ์์ด์. ํ์ง๋ง ์์ง ์คํ์ ๊ธฐ๋ฅ์ด๋ฏ๋ก, ํ๋ก๋์ ํ๊ฒฝ์์ ์ฌ์ฉํ ๋๋ ์ฃผ์๊ฐ ํ์ํด์!
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํ์ฉํ๋ฉด ์ฌ๋ฅ๋ท ํ๋ซํผ์์ ๋ค์ํ ๊ธฐ๋ฅ์ ํจ์จ์ ์ผ๋ก ๊ตฌํํ ์ ์์ ๊ฑฐ์์. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์ ์ธ์ฆ, ๋ก๊น , ์ฑ๋ฅ ์ธก์ ๋ฑ์ ๊ธฐ๋ฅ์ ๋ฐ์ฝ๋ ์ดํฐ๋ก ๊ตฌํํ๋ฉด ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ผ ์ ์์ฃ . ๐๐โฑ๏ธ
์, ์ด์ ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์ ์ฃผ์ ํน์ฑ๋ค์ ๋ชจ๋ ์ดํด๋ดค์ด์. ์ด ๊ฐ๋ ๋ค์ ์ ํ์ฉํ๋ฉด ๋ ์์ ํ๊ณ , ์ ์ง๋ณด์๊ฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ ๊ฑฐ์์. ํ์ ์คํฌ๋ฆฝํธ์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ๋ค์ ํ์ฉํด ์ฌ๋ฌ๋ถ๋ง์ ๋ฉ์ง ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ณด์ธ์! ๐๐จโ๐ป๐ฉโ๐ป
๋ง์น๋ฉฐ ๐ฌ
์ค๋ ์ฐ๋ฆฌ๋ ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์ ๋ค์ํ ํน์ฑ๋ค์ ์ดํด๋ดค์ด์. ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ถํฐ ์์ํด์ ์ ๊ทผ ์ ์ด์, ์์, ์ธํฐํ์ด์ค, ์ ๋ค๋ฆญ, ๊ทธ๋ฆฌ๊ณ ๋ฐ์ฝ๋ ์ดํฐ๊น์ง, ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค์ ํต์ฌ ๊ฐ๋ ๋ค์ ๋ชจ๋ ๋ค๋ค์ฃ .
์ด๋ฌํ ๊ฐ๋ ๋ค์ ์ ํ์ฉํ๋ฉด, ์ฌ๋ฌ๋ถ์ ๋์ฑ ์์ ํ๊ณ ์ ์ง๋ณด์๊ฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ ๊ฑฐ์์. ํนํ ์ฌ๋ฅ๋ท๊ณผ ๊ฐ์ ๋ณต์กํ ํ๋ซํผ์ ๊ฐ๋ฐํ ๋ ์ด๋ฐ ๊ฐ๋ ๋ค์ด ํฐ ๋์์ด ๋ ๊ฑฐ์์.
- ์ ๊ทผ ์ ์ด์๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ๋ณดํธํ๊ณ ,
- ์์์ ํตํด ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ณ ,
- ์ธํฐํ์ด์ค๋ก ์ผ๊ด๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค๊ณ ,
- ์ ๋ค๋ฆญ์ผ๋ก ๋ค์ํ ํ์ ์ ์ ์ฐํ๊ฒ ๋ค๋ฃจ๊ณ ,
- ๋ฐ์ฝ๋ ์ดํฐ๋ก ์ฝ๋์ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ํ์ฅํ ์ ์์ฃ .
ํ์ ์คํฌ๋ฆฝํธ์ ์ด๋ฐ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ๋ค์ ํ์ฉํ๋ฉด, ์ฌ๋ฌ๋ถ์ ์ฝ๋๋ ๋์ฑ ๊ฒฌ๊ณ ํด์ง๊ณ ํ์ฅ์ฑ์ด ๋์์ง ๊ฑฐ์์. ๋ง์น ์ฌ๋ฅ๋ท ํ๋ซํผ์ด ๋ค์ํ ์ฌ๋ฅ์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ฒ๋ผ ๋ง์ด์์! ๐
ํ์ ์คํฌ๋ฆฝํธ ํด๋์ค ๋ง์คํฐํ๊ธฐ, ์ด๋ ์ จ๋์? ์ด์ ์ฌ๋ฌ๋ถ์ ํ์ ์คํฌ๋ฆฝํธ์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ๋ค์ ํ์ฉํด ๋ฉ์ง ํ๋ก์ ํธ๋ฅผ ๋ง๋ค ์ค๋น๊ฐ ๋์์ด์. ์ฌ๋ฌ๋ถ๋ง์ ์ฐฝ์์ ์ธ ์์ด๋์ด๋ฅผ ํ์ ์คํฌ๋ฆฝํธ๋ก ๊ตฌํํด๋ณด์ธ์. ์ฝ๋ฉ์ ์ธ๊ณ์์ ์ฌ๋ฌ๋ถ์ ์ฌ๋ฅ์ด ๋น๋๊ธธ ๋ฐ๋๊ฒ์! ๐ฉโ๐ป๐จโ๐ปโจ
๐ Final Tip: ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ๋ฐฐ์ฐ๋ ๊ณผ์ ์ด ๋๋ก๋ ์ด๋ ค์ธ ์ ์์ด์. ํ์ง๋ง ํฌ๊ธฐํ์ง ๋ง์ธ์! ๊พธ์คํ ์ฐ์ต๊ณผ ์ค์ ํ๋ก์ ํธ ์ ์ฉ์ ํตํด ์ฌ๋ฌ๋ถ์ ์ ์ ๋ ์๋ จ๋ ํ์ ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์๊ฐ ๋ ์ ์์ ๊ฑฐ์์. ํ์ดํ ! ๐ช
- ์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์ฌ๋ฅ๋ท์ ์ต์ AI ๊ธฐ์ ๊ณผ ๋ฒ๋ฅ ์ ๊ธฐ๋ฐํ์ฌ ์์ฌ์ ์ง์ ์ฌ์ฐ๊ถ์ ์ ๊ทน์ ์ผ๋ก ๋ณดํธํ๋ฉฐ,
๋ฌด๋จ ์ฌ์ฉ ๋ฐ ์นจํด ํ์์ ๋ํด ๋ฒ์ ๋์์ ํ ๊ถ๋ฆฌ๋ฅผ ๋ณด์ ํฉ๋๋ค.
ยฉ 2025 ์ฌ๋ฅ๋ท | All rights reserved.
๋๊ธ 0๊ฐ