새소식

프론트엔드/typescript

클래스와 접근 제어자

  • -

안녕하세요 lika-7입니다

이번 시간에는 TypeScript의 클래스와 접근제어자에 대해 정리하겠습니다

클래스 기본 문법

//TypeScript

class UserA {
    constructor(first:string, last:string, age:number){
        this.first = first
        this.last = last
        this.age = age
    }
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}

클래스를 선언하는 위의 문법은 자바스크립트 문법에서는 문제가 없습니다.

하지만 타입스크립트에서 위와 같이 클래스를 선언하면 문제가 생깁니다

UserA안에 first의 내용이 없다고 나옵니다. last와 age 또한 마찬가지 입니다

//TypeScript

class UserA {
    first: string
    last: string
    age: number
    constructor(first:string, last:string, age:number){
        this.first = first
        this.last = last
        this.age = age
    }
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}

constructor 윗부분에 생성자 함수의 속성 타입을 정의해주면 코드상 에러가 사라집니다

클래스 초기화

//TypeScript


class UserA {
    first: string = ''
    last: string = ''
    age: number = 0
    constructor(first:string, last:string, age:number){
        this.first = first
        this.last = last
        this.age = age
    }
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
first: string = ''
last: string = ''
age: number = 0

초기화가 필요하면 “=” 연산자를 이용하여 초기화 하면 됩니다.

접근 제어자 Access modifier

💡
1. 접근 제어자란 클래스의 설계를 위해 클래스의 필드나 메서드에 대한 접근을 제어하기 위해 사용하는 키워드 입니다. 2. 이러한 제어자를 사용해 클래스 내부의 맴버를 외부에서 어떻게 접근 할 수 있는지 결정할 수 있습니다

public 제어자

💡
1. 해당 멤버는 어디서든지 접근할 수 있습니다 2. 클래스 멤버의 접근 제어자가 public인 경우 별도로 명시하지 않아도 됩니다.
클래스 멤버는 클래스 내부에 정의된 변수, 메서드 또는 속성을 가리킵니다
//TypeScript


class UserA {
    first: string = ''
    last: string = ''
    age: number = 0
    constructor(first:string, last:string, age:number){
        this.first = first
        this.last = last
        this.age = age
    }
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}

위 코드에서

first: string = ''
last: string = ''
age: number = 0

부분에 public이라는 접근 제어자를 붙여도 같은 내용 입니다

public first: string = ''
public last: string = ''
public age: number = 0

위와 같이 public 접근 제어자를 넣는다면

//TypeScript

class UserA {
    public first: string = ''
    public last: string = ''
    public age: number = 0
    constructor(first:string, last:string, age:number){
        this.first = first
        this.last = last
        this.age = age
    }
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
class UserB extends UserA{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
class UserC extends UserB{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
const neo = new UserA('Neo','Anderson', 102)
console.log(neo.first)
console.log(neo.last)
console.log(neo.age)

위의 코드에서

1. UserB는 UserA에서 상속받아서 생성된 클래스 입니다. UserB의 this.first, this.last, this.age는 UserA 의 first, last, age 속성에서 받아왔습니다. UserA 속성들의 접근 제어자가 public이기에 어디서든 자유롭게 접근이 가능하여 코드상 문제가 없습니다
2. UserA 생성자를 이용해 생성된 neo 인스턴스 또한 문제 없이 public 속성에 접근 가능합니다

protected

💡
1. 클래스 자신, 파생된 후손 클래스 내에서 접근이 가능합니다
//TypeScript

class UserA {
    public first: string = ''
    protected last: string = ''
    public age: number = 0
    constructor(first:string, last:string, age:number){
        this.first = first
        this.last = last
        this.age = age
    }
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
class UserB extends UserA{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
class UserC extends UserB{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
const neo = new UserA('Neo','Anderson', 102)
console.log(neo.first)
console.log(neo.last)
console.log(neo.age)
protected last: string = ''

UserA 클래스의 last 속성을 protected로 접근제어 한다면

class UserB extends UserA{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
class UserC extends UserB{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}

파생 클래스인 UserB,UserC 는 UserA의 last 속성에 접근이 가능하니 문제가 생기지 않지만

const neo = new UserA('Neo','Anderson', 102)
console.log(neo.first)
console.log(neo.last)
console.log(neo.age)

인스턴스의 부분인 console.log(neo.last) 부분에서 에러가 생깁니다

last 속성은 proteced 되어 있어 UserA와 그 서브 클래스에서만 접근 가능하다고 나옵니다

💡
정리하자면 protected는 클래스 내부에서는 접근 가능하게 하고 클래스 외부에서는 접근 가능하지 못하도록 하겠다는 의미입니다

private

💡
private로 정의된 내용은 내 클래스에서만 접근이 가능 합니다
//TypeScript

class UserA {
    public first: string = ''
    protected last: string = ''
    private age: number = 0
    constructor(first:string, last:string, age:number){
        this.first = first
        this.last = last
        this.age = age
    }
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
class UserB extends UserA{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
class UserC extends UserB{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
const neo = new UserA('Neo','Anderson', 102)
console.log(neo.first)
console.log(neo.last)
console.log(neo.age)
private age: number = 0

private로 선언된 age는 UserA 내에서만 접근 가능하고

class UserB extends UserA{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
class UserC extends UserB{
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
const neo = new UserA('Neo','Anderson', 102)
console.log(neo.first)
console.log(neo.last)
console.log(neo.age)

UserB, UserC 클래스와 neo 인스턴스에서는 접근이 불가능 합니다

age 속성은 private 임으로 UserA 클래스에서만 접근이 가능하다고 합니다

접근 제어자는 속성 뿐 아니라 메서드에서도 적용이 가능합니다
class UserB extends UserA{
    protected getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}

접근 제어자 - 그 외 패턴

//TypeScript

class UserA {
    public first: string = ''
    protected last: string = ''
    private age: number = 0
    constructor(first:string, last:string, age:number){
        this.first = first
        this.last = last
        this.age = age
    }
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}

위의 내용을 보았을 때 생성자 선언에 똑같은 내용이 너무 많아서 보기 불편합니다.

  1. “속성”을 만들고 “속성”을 초기화 하고
  1. 생성자 안에서 같은 “속성”을 매개변수로 받아서
  1. 생성자 “속성”을 클래스의 속성으로 초기화 한다

똑같은 “속성”을 총 3번이나 작성하였습니다. 이를 아래와 같이 수정 할 수 있습니다

//TypeScript

class UserA {
    constructor(public first:string = '', protected last:string = '', private age:number = 0){
    }
    getAge(){
        return `${this.first} ${this.last} is ${this.age}`
    }
}
💡
매개변수에서 접근 제어자를 이용하면서 생성자 함수의 속성을 정의하고 초기화 할 수 있습니다
public 접근제어자는 클래스 바디에서만 생략 가능합니다. 매개변수로 되어 있을 때는 명시해주어야 합니다

'프론트엔드 > typescript' 카테고리의 다른 글

제네릭(Generic) -클래스  (0) 2023.09.20
제네릭(Generic) -함수  (0) 2023.09.20
함수 - 오버로딩  (0) 2023.09.19
함수 - 명시적 this 타입  (0) 2023.09.19
객체 데이터 타입 지정  (0) 2023.09.19
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.