Class

3개의 게시글

TypeScript

[TypeScript] 인터페이스 구현하기 (implements)

November 27, 2025

타입스크립트의 인터페이스(Interface) 는 객체의 타입을 정의하는 용도뿐만 아니라, 클래스의 설계도(Blueprint) 역할도 수행할 수 있다. 쉽게 말해, "이 클래스는 적어도 이 프로퍼티와 이 메서드는 무조건 가지고 있어야 해!"라고 강제하는 것이다. 이때 사용하는 키워드가 바로 implements다. 1. 인터페이스로 설계도 만들기 먼저 게임 캐릭터를 만든다고 가정하고, 캐릭터라면 가져야 할 필수 요소를 인터페이스로 정의해보자. TypeScript interface CharacterInterface { name: string; // 이름 moveSpeed: number; // 이동 속도 move(): void; // 이동 메서드 } 이제 이 인터페이스는 하나의 약속(Contract) 이 된다. "누구든 CharacterInterface를 구현하려면 name, moveSpeed, move()를 반드시 가지고 있어야 한다"는 규칙이 생긴 것이다. --- 2. 클래스에서 구현하기 (implements) 클래스 이름 뒤에 implements 키워드와 인터페이스 이름을 적어주면 된다. TypeScript class Character implements CharacterInterface { // 생성자 매개변수에 접근 제어자를 붙여 필드 선언과 초기화를 한 번에 해결 constructor( public name: string, public moveSpeed: number, private extra: string // 인터페이스에 없는 건 마음대로 추가 가능 ) {} // 인터페이스에 정의된 메서드 구현 move(): void { console.log(${this.moveSpeed} 속도로 이동!); } } 이제 Character 클래스는 CharacterInterface의 규칙을 따르게 된다. 만약 인터페이스에 정의된 프로퍼티나 메서드를 하나라도 빼먹으면 에러가 발생한다. 구현 시 주의할 점 (접근 제어자) 인터페이스에 정의된 프로퍼티나 메서드는 클래스에서 구현할 때 무조건 public 이어야 한다. 인터페이스는 기본적으로 "외부에 노출되는 인터페이스(접점)"를 정의하는 것이기 때문에, 이를 private이나 protected로 숨길 수 없다. TypeScript interface CharacterInterface { name: string; } class Character implements CharacterInterface { // ❌ 에러: 인터페이스의 속성은 private일 수 없음 // private name: string; constructor(public name: string) {} // ✅ public은 가능 } > 참고: 인터페이스에 정의되지 않은 추가 필드(private extra 등)는 private이나 protected로 자유롭게 설정할 수 있다. > --- 3. 요약 1. 설계도 역할: 인터페이스를 사용해 클래스가 가져야 할 필드와 메서드의 구조를 정의할 수 있다. 2. implements: 클래스가 특정 인터페이스를 준수하도록 강제하는 키워드다. 3. 규칙: 인터페이스에 정의된 속성은 클래스에서 반드시 구현해야 하며, 접근 제어자는 public 이어야 한다.

TypeScriptStudyClassInterfaceOOP
TypeScript

[TypeScript] 클래스 접근 제어자

November 27, 2025

접근 제어자(Access Modifier) 는 클래스의 특정 필드나 메서드에 접근할 수 있는 범위를 설정하는 기능이다. 자바스크립트(ES6) 클래스에는 없는 타입스크립트만의 고유 기능으로, 객체 지향 프로그래밍의 특징인 은닉화(Encapsulation) 를 돕는다. 타입스크립트에는 다음 3가지의 접근 제어자가 존재한다. 1. public: 모든 범위에서 접근 가능 2. protected: 클래스 내부 + 파생(자식) 클래스 내부에서만 접근 가능 3. private: 오직 클래스 내부에서만 접근 가능 --- 1. public (공공의) public은 말 그대로 '공공의'라는 뜻으로, 어디서든 자유롭게 접근할 수 있다. 접근 제어자를 별도로 명시하지 않으면 기본적으로 public으로 설정된다. TypeScript class Employee { // 필드 (기본적으로 public) name: string; public age: number; // 명시적으로 작성해도 됨 public position: string; constructor(name: string, age: number, position: string) { this.name = name; this.age = age; this.position = position; } work() { console.log("일함"); } } const employee = new Employee("조태민", 25, "developer"); // ✅ 외부에서 자유롭게 접근 및 수정 가능 employee.name = "강두칠"; employee.age = 21; employee.position = "디자이너"; --- 2. private (사적인) private은 오직 해당 클래스 내부에서만 접근할 수 있다. 외부에서는 물론이고, 상속받은 자식 클래스에서도 접근할 수 없다. 가장 엄격한 제어자다. TypeScript class Employee { private name: string; // 🔒 private 설정 public age: number; public position: string; constructor(name: string, age: number, position: string) { this.name = name; this.age = age; this.position = position; } work() { // ✅ 클래스 내부에서는 접근 가능 console.log(${this.name}이 일함); } } const employee = new Employee("조태민", 25, "developer"); // ❌ 오류 발생: 외부에서 접근 불가 // employee.name = "강두칠"; --- 3. protected (보호된) protected는 public과 private의 중간 단계다. 외부에서는 접근할 수 없지만, 클래스 내부와 이를 상속받은 파생 클래스(자식) 에서는 접근할 수 있다. TypeScript class Employee { private name: string; // 나만 쓸 거야 protected age: number; // 자식한테는 물려줄 거야 public position: string; // 다 써도 돼 constructor(name: string, age: number, position: string) { this.name = name; this.age = age; this.position = position; } } // Employee를 상속받은 자식 클래스 class ExecutiveOfficer extends Employee { func() { // this.name; // ❌ 오류 (private은 자식도 접근 불가) this.age; // ✅ 가능 (protected는 자식 접근 허용) } } const employee = new Employee("조태민", 25, "developer"); // ❌ 오류: 외부에서는 protected도 접근 불가 // employee.age = 30; 🔍 접근 범위 한눈에 보기 | 제어자 | 클래스 내부 | 자식 클래스 | 클래스 외부 | | --- | --- | --- | --- | | public | ⭕️ | ⭕️ | ⭕️ | | protected | ⭕️ | ⭕️ | ❌ | | private | ⭕️ | ❌ | ❌ | --- 4. 꿀팁: 생성자 매개변수로 필드 생략하기 타입스크립트에서는 생성자(constructor)의 매개변수에 접근 제어자를 붙여주면, 필드 선언과 초기화 코드를 한 번에 생략할 수 있다. Before: 일반적인 작성법 필드 선언하고, 생성자에서 매개변수 받고, this로 할당하고... 코드가 길다. TypeScript class Employee { private name: string; protected age: number; public position: string; constructor(name: string, age: number, position: string) { this.name = name; this.age = age; this.position = position; } } After: 접근 제어자 활용 (추천 👍) 생성자 매개변수 앞에 public, private, protected 중 하나만 붙이면, 타입스크립트가 알아서 "아, 이거 필드로 만들고 값도 자동으로 넣으라는 거구나" 라고 이해한다. TypeScript class Employee { // 필드 선언 제거! // 초기화 코드(this.xxx = xxx) 제거! constructor( private name: string, protected age: number, public position: string ) {} // 생성자 본문이 비어있어도 됨 work() { console.log(${this.name} 일함); } } 코드가 훨씬 간결해지므로 실무에서 매우 자주 사용하는 패턴이다. --- 요약 1. public: 기본값. 어디서든 접근 가능. 2. private: 내 클래스 안에서만 접근 가능. (가장 엄격) 3. protected: 내 클래스 + 상속받은 자식 클래스에서 접근 가능. 4. 필드 생략: 생성자 매개변수에 접근 제어자를 붙이면 필드 선언과 초기화를 자동으로 처리해 준다.

TypeScriptStudyClassOOPAccessModifier
TypeScript

[TypeScript] 클래스(Class)

November 27, 2025

자바스크립트(ES6)의 클래스 문법에 타입스크립트만의 타입 시스템이 더해지면 어떻게 될까? 필드 선언부터 상속 시 주의할 점까지, 타입스크립트에서의 클래스 사용법을 정리해 본다. 1. 클래스 필드 선언 타입스크립트에서 클래스를 만들 때는 필드(Field) 를 선언할 때 반드시 타입을 함께 정의해야 한다. TypeScript class Employee { // 필드 name: string = ""; age: number = 0; position: string = ""; // 메서드 work() { console.log("일함"); } } 주의할 점 1. 타입 주석 필수: 타입을 정의하지 않으면 암시적 any 타입으로 추론된다. strict 모드(엄격한 타입 검사)에서는 이것이 오류로 간주된다. 2. 초기값 설정: 생성자(constructor)에서 값을 초기화하지 않는다면, 필드 선언 시 기본값을 할당해 줘야 한다. 그렇지 않으면 "초기화되지 않았다"는 오류가 발생한다. --- 2. 생성자(Constructor)와 선택적 프로퍼티 생성자를 이용해 인스턴스 생성 시점에 필드 값을 초기화할 수 있다. 생성자에서 할당이 확실하게 이루어진다면, 필드 선언부에서 초기값을 생략해도 된다. TypeScript class Employee { // 필드 name: string; age: number; position: string; // 생성자 constructor(name: string, age: number, position: string) { this.name = name; this.age = age; this.position = position; } work() { console.log("일함"); } } 선택적 프로퍼티 (Optional Property) 특정 필드가 있어도 되고 없어도 되는 경우라면, 필드 이름 뒤에 물음표(?)를 붙여 선택적 프로퍼티로 만들 수 있다. TypeScript class Employee { // ... position?: string; // 선택적 프로퍼티 constructor(name: string, age: number, position: string) { // ... this.position = position; } } --- 3. 클래스는 타입이다 타입스크립트의 클래스는 값이자 동시에 타입으로도 사용된다. 즉, 클래스로 만든 인스턴스뿐만 아니라, 그 클래스의 형태(구조)를 가진 객체라면 해당 클래스 타입으로 정의할 수 있다. TypeScript class Employee { // ... (위와 동일) } // Employee 클래스를 타입으로 사용 const employeeC: Employee = { name: "조태민", age: 25, position: "Developer", work() { console.log("일하는 중"); }, }; 변수 employeeC는 Employee 클래스의 인스턴스(new Employee(...))가 아니지만, Employee가 가진 필드와 메서드를 모두 가지고 있으므로 Employee 타입으로 인정된다. (구조적 타이핑) --- 4. 상속 (Inheritance) extends 키워드를 사용해 클래스를 상속받을 수 있다. 이때 생성자(constructor)를 다룰 때 주의해야 할 규칙이 있다. TypeScript // Employee를 상속받는 ExecutiveOfficer 클래스 class ExecutiveOfficer extends Employee { officeNumber: number; constructor( name: string, age: number, position: string, officeNumber: number ) { super(name, age, position); // ✅ 반드시 최상단에서 호출! this.officeNumber = officeNumber; } } 상속 시 주의사항 (super) 파생 클래스(자식)에서 생성자를 정의했다면, 반드시 super() 메서드를 호출해 부모 클래스의 생성자를 실행해야 한다. 또한 super() 호출은 this에 접근하기 전, 생성자 내부의 최상단에 위치해야 한다. --- 요약 1. 필드 선언: 필드의 타입과 초기값을 명시해야 안전하다. 2. 생성자: 필드 초기화의 역할을 하며, ?를 써서 선택적 필드를 만들 수 있다. 3. 타입으로서의 클래스: 클래스 이름은 그 자체로 타입으로 사용될 수 있다. 4. 상속: extends를 사용하며, 자식 클래스 생성자에서는 super()를 가장 먼저 호출해야 한다.

TypeScriptStudyClassOOP