Ted's Codding study

접근제한자(접근제어자, Access Modifiers) 본문

TypeScript

접근제한자(접근제어자, Access Modifiers)

Ted93 2024. 6. 26. 19:55

캡슐화

  • 클래스의 내부 데이터를 외부에서 직접 접근하는 것을 제한, 데이터의 안정성을 보장하는 방식

1. 접근제한자의 정의

클래스의 내부 데이터를 외부에서 직접 접근하는 것을 제한하여
사용자의 코드 흐름에 맞게 데이터를 처리하는 방식

 

2. 접근제한자의 종류(3가지)

1. public

  • 어디서든 접근 가능(기본값 - 생략 시)
  • 기본적으로 모든 멤버가 가지고 있는 접근 제한자
  • 프로그램의 어느 곳에서나 접근 가능
  • 접근 제한자가 명시되지 않은 멤버는 모두 public으로 설정

 

2. private

  • 해당 클래스 내부에서만 접근 가능
  • 클래스 외부에서 private한 멤버에 접근할 경우 오류

 

3. protected

  • 해당 클래스 및 상속받은 하위 클래스에서만 접근 가능
  • 기본적으로 하위 클래스는 상위 클래스의 멤버에 접근 가능하지만
  • 만약 해당 멤버가 private이라면 접근 X

 

3. 접근제한자 사용 목적

  • 클래스의 내부 구현을 숨기거나, 특정 멤버의 접근을 제한할 때 사용 안정성과 유지보수성을 높이기 위함
// Employee 클래스 정의
class Employee {
  // 멤버 변수 정의(접근 제한자)
  public name: string; // 이름
  private salary: number; // 급여
  protected department: string; // 해당 클래스 | 하위 클래스에서만 접근 가능

  constructor(name: string, salary: number, department: string) {
    this.name = name;
    this.salary = salary;
    this.department = department;
  }

  public displayInfo(): void {
    console.log(
      `이름: ${this.name} / 부서: ${this.department} / 급여: ${this.salary}`,
    );
    console.log(`보너스: ${this.calculateBonus()}`);
  }

  private calculateBonus(): number {
    return this.salary * 0.1;
  }
}

// Employee 클래스 사용 예제(인스턴스화)
let emp1 = new Employee('테드', 50000, 'IT');
console.log(emp1.name); // 테드
console.log(emp1.salary); // Error
// 'salary' 속성은 private이며 'Employee' 클래스 내에서만 액세스할 수 있습니다.
console.log(emp1.department); // Error
// 'department' 속성은 보호된 속성이며 'Employee' 클래스 및 해당 하위 클래스 내에서만 액세스할 수 있습니다.
emp1.displayInfo(); // 이름: 테드 / 부서: IT / 급여: 50000
										// 보너스: 5000
emp1.calculateBonus(); // Error
// 'calculateBonus' 속성은 private이며 'Employee' 클래스 내에서만 액세스할 수 있습니다.

 

4. 생성자의 경우 멤버 선언 외에도 생성자의 매개변수 앞에 접근 제한자 명시 가능

  • 해당 매개변수는 같은 이름의 속성(멤버 변수)으로 선언,
    해당 매개변수의 인자는 암묵적으로 인스턴스에 할당
  • 위의 User 클래스와 동일
class User {
  public id: string;
  private password: string;

  constructor(id: string, password: string) {
    this.id = id;
    this.password = password;
  }
}

class User2 {
  constructor(
    public id: string,
    private password: string,
  ) {}
}

// User와 User2는 완전 동일한 코드

let user1 = new User('qwe123', 'qwert123');
console.log(user1.id); // qwe123
// console.log(user1.password); // Error

let user2 = new User('ted123', 'tedfriend123'); // ted123
console.log(user2.id);
// console.log(user2.password); // Error

 

5. 연습문제

문제1

Car 클래스 생성
클래스는 model과 year 두 개의 멤버 변수
매개변수로 두 개의 멤버 변수를 받는 생성자 생성
매개변수에 접근 제한자를 사용하여 변수 선언과 생성자의 초기화를 결합하여 표시
getModelAndYear라는 메서드 포함
"This car is a {model} from {year}."를 출력

클래스 생성 후
car1 인스턴스 생성
model은 '아이오닉5' year은 '2024'로 설정
car1 인스턴스의 getModelAndYear 메서드를 호출
정답
// Car 클래스 생성
class Car {
  // public model: string;
  // public year: number;
  // constructor(model: string, year: number) {
  //   this.model = model;
  //   this.year = year;
  // }
  constructor(
    public model: string,
    public year: number,
  ) {}

  getModelAndYear() {
    console.log(`This car is a ${this.model} from ${this.year}.`);
  }
}

// car1 인스턴스 생성
let car1 = new Car('아이오닉5', 2024);
car1.getModelAndYear(); // This car is a 아이오닉5 from 2024.

 

문제2

  • 은행 계좌 클래스 생성 예제
    요구 사항
    BankAccount 클래스 완성 후 메서드 적절히 사용해보기
class BankAccount {
  // - accountNumber(계좌 번호), balance(잔액) 속성은 외부에서 직접 접근할 수 없는 속성
  // - 생성자: 계좌 번호와 초기 잔액을 매개변수로 받아 객체를 초기화
  //           초기 잔액은 선택적으로 처리(기본값 0)
  // - 메서드
  // 1. deposit(amount: number): 입금액을 받아 잔액을 증가
  // 2. withdraw(amount: number): 출금액을 받아 잔액을 감소
  //                      잔액보다 많은 금액을 출금할 수 X - 출금액이 잔고를 초과하였습니다
  // 3. getBalance(): 현재 잔액을 반환
  // 4. getAccountNumber(): 계좌번호를 반환
}

// let accountA = new BankAccount('123-456');
정답
class BankAccount {
  constructor(
    private accountNumber: string,
    private balance: number = 0,
  ) {}
  deposit(amount: number) {
    this.balance += amount;
    console.log(`입금액 ${amount}, 현재 잔액 ${this.balance}`);
  }
  withdraw(amount: number) {
    if (this.balance >= amount) {
      this.balance -= amount;
      console.log(`출금액 ${amount}, 현재 잔액 ${this.balance}`);
    } else console.log('출금액이 잔고를 초과하였습니다');
  }
  getBalance() {
    return this.balance;
  }
  getAccountNumber() {
    return this.accountNumber;
  }
}

let accountA = new BankAccount('123-456');
console.log(accountA.getBalance()); // 0
accountA.deposit(30000); // 입금액 30000, 현재 잔액 30000
accountA.deposit(90000); // 입금액 90000, 현재 잔액 120000
accountA.withdraw(100000); // 출금액 100000, 현재 잔액 20000
console.log(accountA.getBalance()); // 20000
accountA.withdraw(50000); // 출금액이 잔고를 초과하였습니다
console.log(accountA.getBalance()); // 20000
console.log(accountA.getAccountNumber()); // 123-456

 

 

노션으로 보고 싶다면?

https://short-echidna-b16.notion.site/Access-Modifiers-b2e0ff3b65c64ca99c24cd7c23d25dba?pvs=4

 

접근제한자(접근제어자, Access Modifiers) | Notion

목차

short-echidna-b16.notion.site