[TypeScript] 타입스크립트의 객체지향언어 - 클래스와 객체, 접근지정자, getter와 setter

구조체, 공용체, 열거형, 인터페이스, 클래스 

 

클래스

연관된 변수와 함수들을 한 덩어리로 묶음

 

클래스와 객체 

클래스(설계도, 생산틀)는 객체의 뼈대, 객체는 클래스의 실체

 

//일반적인 직원 정보
let empName : string;
let age : number;
let empJob : string;

function printEmp(empName : string, age : number, empJob : string) : void{     
    console.log(`${empName}의 나이는 ${age}이고, 직업은 ${empJob}입니다.`);
}

printEmp('kim', 20, 'developer');

이 코드에서는, empName, age, empJob이 각각 별개의 변수입니다. 만약 직원이 100명이면 어떻게 될까요?

empName1, empName2... 이런 식으로 변수를 엄청나게 만들어야 합니다.

 

클래스를 쓰면 Employee라는 하나의 틀 안에 이름, 나이, 직업을 패키지처럼 묶어버릴 수 있습니다.

 

멤버변수 == 속성 == 프로퍼티

멤버함수 == 메소드

class Employee {
    empName : string;
    age : number;
    empJob : string;

	// 생성자
    constructor(name: string, age: number, job: string) { 
        this.empName = name;
        this.age = age;
        this.empJob = job;
    }

    printEmp = () : void => {      
        console.log(`${this.empName}의 나이는 ${this.age}이고, 직업은 ${this.empJob}입니다.`);
    }
}

let employee1 = new Employee('kim', 20, 'developer'); // new 키워드에서 생성자 바로 실행됨
employee1.printEmp();

 

접근지정자

1. public (기본값)

  • 범위: 어디서든 자유롭게 접근 가능.
  • 접근 제어자를 따로 쓰지 않으면 기본적으로 public이 됩니다. (작성하신 코드의 상태)
  • 외부에서 마음대로 값을 바꿀 수 있어 위험할 수 있습니다. (예: 나이를 -100으로 수정 가능)

2. private (비밀)

  • 범위: 오직 해당 클래스 내부에서만 접근 가능.
  • 클래스 외부(employee1.xxx)에서 접근하려고 하면 에러가 발생합니다. 데이터를 보호(캡슐화)할 때 사용합니다.

3. protected (가족)

  • 범위: 해당 클래스 내부 + 상속받은 자식 클래스까지 접근 가능.
  • 외부에서는 안 보이지만, 이 클래스를 물려받은 '팀장'이나 '신입' 클래스에서는 사용할 수 있습니다.
class Employee {
    private _empName: string; // 클래스 밖에서 못 읽음
    public age: number;      // 어디서든 읽고 쓰기 가능
    protected empJob: string; // 나중에 상속받은 자식은 사용 가능

    constructor(name: string, age: number, job: string) {
        this._empName = name;
        this.age = age;
        this.empJob = job;
    }

    printEmp = () : void => {      
        // 클래스 내부이므로 private인 empName에 접근 가능!
        console.log(`${this.empName}의 나이는 ${this.age}입니다.`);
    }
}

let employee1 = new Employee('kim', 20, 'developer');

console.log(employee1.age);     // ✅ 가능 (public)
// console.log(employee1._empName); // ❌ 에러! (private이라 밖에서 안 보임)
// console.log(employee1.empJob);  // ❌ 에러! (protected라 외부 접근 불가)

 

Getter와 Setter

private으로 설정된 변수는 클래스 외부에서 직접 수정하거나 읽을 수 없도록 잠금 상태가 된 것과 같습니다. 하지만 상황에 따라 그 값을 가져오거나 안전하게 수정해야 할 때가 있죠. 이때 사용하는 전용 통로가 바로 Getter와 Setter입니다.

  • Getter (획득자): private 변수의 값을 외부로 전달해주는 메서드입니다. (get 키워드 사용)
  • Setter (설정자): 외부에서 들어온 값을 검사한 뒤 private 변수에 저장해주는 메서드입니다. (set 키워드 사용)
class Employee {
    // 생성자
    constructor(
    	private _empName : string,
        private _age : number,
        private _empJob : string) {
        
    }
    
    get empName() {
        return this._empName;
    }

    set empName(val : string) {
        this._empName = val;
    }

    printEmp = () : void => {      
        console.log(`${this._empName}의 나이는 ${this._age}이고, 직업은 ${this._empJob}입니다.`);
    }
}

let employee1 = new Employee('kim', 20, 'developer'); // new 키워드에서 생성자(constucor) 실행됨

employee1.empName = 'lee';
employee1.printEmp();

 

이로써 데이터 무결성(안전성)을 유지할 수 있습니다.

  • 예를 들어, 나이(age)를 -500세로 설정하려 할 때, Setter에서 이를 체크하여 막을 수 있습니다.
  • 이름을 가져올 때 항상 "님"을 붙여서 가져오게 하는 등 추가 로직을 넣을 수 있습니다.
class Employee {
    private _empName: string;
    private _age: number; // 내부 전용 변수

    constructor(name: string, age: number) {
        this._empName = name;
        this._age = age;
    }

    // 1. Getter: 나이를 읽을 때 실행됨
    get age(): number {
        console.log("나이를 조회합니다.");
        return this._age;
    }

    // 2. Setter: 나이를 수정할 때 실행됨 (검증 로직 추가 가능)
    set age(value: number) {
        if (value < 0) {
            console.log("에러: 나이는 음수가 될 수 없습니다!");
            return;
        }
        this._age = value;
    }
}

let employee1 = new Employee('kim', 20);

// 사용법은 일반 변수와 똑같지만, 내부적으로는 get/set 메서드가 실행됩니다.
employee1.age = 25;      // Setter 실행
console.log(employee1.age); // Getter 실행 -> "25" 출력

employee1.age = -5;      // Setter 실행 -> "에러 메시지" 출력 (값 안 변함)