본문 바로가기
  • 실행력이 모든걸 결정한다
Frontend/TypeScript

[TypeScript] 클래스

by 김코더 김주역 2021. 4. 23.
반응형

1. 클래스 기본

클래스 내부 변수를 프로퍼티라고 하며, 클래스 내부 함수를 메소드라고 한다.

프로퍼티와 메소드는 constructor(생성자)를 이용하여 객체 생성시 초기화 할 수 있다.

 

예제

class Animal{
    name:string;
    species:string;
    age:number;
    neuter:boolean;
    constructor(
        name:string,
        species:string,
        age:number,
        neuter:boolean    
    ){
        this.name=name;
        this.species=species;
        this.age=age;
        this.neuter=neuter;
    }
}

let a:Animal = new Animal("lamb", "dog", 16, false);
let b:Animal = new Animal("happy", "cat", 5, true);

console.log(a.name);
console.log(b.name);

 

실행 결과

 

 

2. 접근 제어자

접근 제어자로 프로퍼티와 메소드의 접근 범위를 설정할 수 있다.

접근 제어자의 종류로는 public, protected, private가 있으며, 변수 선언부 맨 앞에 작성하면 된다.

  • public : 모두 접근 가능, 기본값이기 때문에 생략 가능하다.
  • protected : 자신 클래스 또는 후손 클래스에서만 접근 가능
  • private : 자신 클래스에서만 접근 가능

 

예제 1

아래와 같이 생성자에서 프로퍼티 앞에 접근자를 달아주면, 정의와 초기화를 같이 할 수 있기 때문에 코드를 많이 단축할 수 있다.

class Animal{
    constructor(
        public name:string,
        public species:string,
        public age:number,
        public neuter:boolean    
    ){}
}

let a:Animal = new Animal("lamb", "dog", 16, false);
let b:Animal = new Animal("happy", "cat", 5, true);

console.log(a.name);
console.log(b.name);

실행 결과

 

예제 2

접근 제어자가 private인 변수에는 외부에서 접근할 수 없으므로 빨간줄이 그어졌다.

 

 

3. Getter, Setter

Getter 메소드는 멤버 변수값을 외부로 반환해주는 메소드이며, Setter 메소드는 멤버 변수값을 외부에서 수정할 수 있도록 하는 메소드이다.

메소드명은 일반적으로 get/set+변수명의 조합으로 표기하며, 메소드명에서 변수명의 첫자는 대문자로 한다.

 

예제

접근 제어자가 private인 멤버 변수도 Getter, Setter메소드로 접근할 수 있다.

class Animal{
    constructor(
        private name:string,
        private species:string,
        private age:number,
        private neuter:boolean    
    ){}

    addAge():void{
        this.age+=1;
    }

    getName():string { //Getter 메소드
        return this.name;
    }

    setName(name:string):void { //Setter 메소드
        this.name=name;
    }

    getAge():number {
        return this.age;
    }

}

let a:Animal = new Animal("lamb", "dog", 16, false);
let b:Animal = new Animal("happy", "cat", 5, true);

a.setName("joy");
console.log(a.getName());
b.addAge();
console.log(b.getAge());

 

실행 결과

 

 

4. 상속

자식 클래스는 부모 클래스를 상속받아서 부모 클래스에 있는 프로퍼티, 메소드를 재사용할 수 있게 된다.

재사용 했을 시 우선 순위는 자식 클래스가 더 높고, 접근 제한자 범위는 자식 클래스가 더 넓어야 한다.

부모 클래스를 상속 받을 때 사용하는 키워드는 extends이며, 다중 상속은 불가능하다.

그리고 상속받은 자식 클래스의 생성자에서는 super()를 호출해야 하며, super()은 부모 객체의 생성자이다.

 

super()를 호출하지 않았을 때의 오류 메세지

 

예제

Silver, Gold 클래스는 User 클래스를 상속받았으며, User 클래스의 멤버 변수인 company를 가져와 쓸 수 있었다.

그리고 super() 메소드를 이용하여 자식 객체의 프로퍼티 값들을 부모 객체로 전달해주었다.

class User{
    protected company:string = "ABC";
    constructor(
        private id:string,
        private point:number,
        private rank:string
    ){
        console.log("User Class");
    }
    getRank():string{
        return this.rank;
    }
}

class Silver extends User{
    constructor(
        private _id:string,
        private _point:number,
    ){
        super(_id, _point, "Silver");
        console.log("Silver Class");
    }
    getCompany():string{
        return this.company;
    }
}

class Gold extends User{
    constructor(
        private _id:string,
        private _point:number,
    ){
        super(_id, _point, "Gold");
        console.log("Gold Class");
    }
    getCompany():string{
        return this.company;
    }
}

let userA = new Silver("111403",205);
console.log(userA.getRank());
console.log(userA.getCompany());

let userB = new Gold("111500",664);
console.log(userB.getRank());
console.log(userB.getCompany());

 

실행 결과

부모 클래스에 있는 getRank() 메소드와 자식 클래스에 있는 getCompany() 메소드가 모두 잘 실행되었다.

 

 

5. 추상 클래스

추상 클래스는 한 개 이상의 추상 요소(프로퍼티, 메소드)를 가지는 클래스이다.

추상 프로퍼티와 추상 메소드는 접근 제한자와 메소드명 사이에 abstract라고 표기한다.

그리고 추상 요소들은 private 접근 제한자와 같이 쓸 수 없다.

 

추상 클래스를 상속받는 클래스에서는 반드시 모든 추상 요소들에 대해 재정의 해야 하며, 재정의하지 않으면 아래와 같은 오류 메세지가 나온다.

 

오류 부분

 

오류 메세지

 

추상 클래스는 인터페이스와 비슷한 개념인데 과연 무슨 차이점이 있을까?

먼저, 추상 클래스는 다중 상속이 불가능하며 일반 변수, 일반 메소드, 추상 메소드로 구성된다.

하지만 인터페이스는 다중 상속이 가능하며 상수, 추상 메소드로만 구성된다.

 

일반적으로 추상 클래스는 기능을 확장하기 위한 목적으로 사용되고, 인터페이스는 구현 객체의 같은 동작을 보장하기 위한 목적으로 사용된다.

 

예제

abstract class Animal{
    abstract speices:string;
    abstract sound():string;
}

class Dog extends Animal{
    speices:string = "poodle";
    sound(){
        return "woof! woof!";
    }
}

let lamb = new Dog();
console.log(lamb.speices);
console.log(lamb.sound());

 

실행 결과

 

 

6. static

정적(static) 변수는 여러 객체끼리 값을 공유하는 변수이다.

그리고 정적 요소에 접근할 때에는 객체가 아닌 클래스를 통해 바로 접근한다.

무슨 말인지 잘 이해가 되지 않아도 아래 예제를 보면 이해가 쉬울 것이다.

 

예제

나, 어머니, 아버지 총 3명이 하나의 통장을 같이 사용하는 상황이다.

즉, 잔액은 공유 되어야 하는 값이다.

class Account{
    public static balance:number; //잔액은 모두 공유 되어야 한다.
    constructor(){
        Account.balance=5000; //클래스(Account)를 통한 접근
    }
    deposit(money:number){ //입금
        Account.balance+=money;
    }
    withdraw(money:number){ //출금
        Account.balance-=money;
    }
}

let me = new Account();
let mother = new Account();
let father = new Account();

me.deposit(1000);
console.log(Account.balance); //클래스(Account)를 통한 접근

mother.deposit(2000);
console.log(Account.balance);

father.withdraw(5000);
console.log(Account.balance);

 

실행 결과

잘 누적되었다.

반응형

댓글