본문 바로가기

Front-End: Web/TypeScript

[코딩애플] ts part 2-5. protected & static

반응형

class에서 사용가능한 protected, static 키워드

복습) class를 복사해서 갖다쓰고 싶을 때 -> 'extends'

class User {
    x = 10;
}

class NewUser extends User {
    
}

let 사람 = new NewUser();
conosle.log(사람); // NewUser {x: 10}

복습) private 붙이면 class {} 안에서만 사용가능

class User {
    private x = 10;
}

protected 키워드

  • private, protected 붙이면 class {}안에서만 사용 가능
  • protected가 private의 연장선

protected 붙이면 현재 class {} 안에서 + extends 된 class {} 안에서 사용 가능

private를 쓰면 class User에서만 쓸 수 있고, extends한 NewUser에선 사용할 수 없다.

class User {
    private x = 10;
}
class NewUser extends User {
    
}
let 사람 = new NewUser();
conosle.log(사람); // NewUser 

하지만 protected로 쓰면 extends한 NewUser에서도 사용할 수 있다.

class User {
    protected x = 10;
}
class NewUser extends User {
    doThis(){
        this.x = 20; // ⬅️ this.x를 갖다 쓸 수 있음
    }
}

protected vs private

  • **protected**: extends된 class는 사용가능, 자식들 사용불가능
  • **private**: extends된 class는 사용불가능, 자식들 사용불가능

static 키워드

static 키워드 붙이면 부모 class에 직접 부여됨 (+자식에게 안물려줌 / extends하면 잘 따라옴)

class User {
    x = 10;
    y = 20;
}

let 자식 = new User();
console.log(자식); // User {x: 10, y: 20}

여기에 static 키워드를 부여한다면?

class User {
    static x = 10;
    y = 20;
}

let 자식 = new User();
console.log(자식); // User {y: 20}

x가 없어진다. 자식들이 물려받지 못하게 부모만 갖다 쓸 수 있게 필드를 만들었기 때문이다.

class의 주요 기능인 object 복사를 막는 변수다.

console.log(자식.x); // 에러 발생

그럼 x는 어디 갖다 쓸 수 있냐?

console.log(User.x); // 10. -> 부모만 갖다 쓸 수 있음
console.log(User.y); // 에러 발생 -> 자식만 사용 가능하기 때문.

private / protected / public + static 가능

class User {
    private static x = 10;
    public static y = 20;
}

대체 언제 활용해야 함?

class User {
    intro = '전문가입니다'
}
let 철수 = new User();
console.log(철수); // User {intro: '전문가입니다'}

만약 여기서

'python 전문가입니다',

'ts 전문가입니다',

'js 전문가입니다'

처럼 가끔 이런걸 물려주고 싶다면?

class User {
    skill = 'js';
    intro = this.skill + '전문가입니다';
}

let 철수 = new User();
console.log(철수); // User {skill: 'js', intro: 'js전문가입니다'}

근데 skill이라는 중요한 변수들도 다 물려받는다. 얘는 감추고 싶은데.. 이럴 때 skill을 못 물려받게 감출 수 있다. 자식들이 수정할 수 없도록.

class User {
    static skill = 'js'
    intro this.skill + '전문가입니다'
}

그러면 자식들은 skill을 물려받을 수가 없다. 무조건 User 클래스만 갖다 쓸 수 있다.

근데 이상하게 뜬다!

console.log(철수); // User {intro: 'undefined전문가입니다'}

왜냐하면 User 클래스에서만 갖다 쓸 수 있기 때문이다. 그래서 this.skill이 아니라 User.skill로 작성해야 한다.

class User {
    static skill = 'js';
    intro = User.skill + '전문가입니다';
}

이렇게 만들어 놓으면 모든 자식들은 'js전문가입니다 만 나올거다.

let 철수 = new User();
console.log(철수); // User {intro: 'js전문가입니다'}

let 철수2 = new User();
console.log(철수2); // User {intro: 'js전문가입니다'}

근데 만약 중간에 skill을 다른 걸로 바꿔서 철수2만 skill을 바꾸고 싶다면? User.skill에 접근해서 변경한다.

class User {
    static skill = 'js';
    intro = User.skill + '전문가입니다';
}
let 철수 = new User();
console.log(철수); // User { intro: 'js전문가입니다'}

User.skill = 'ts';

let 철수2 = new User();
console.log(철수2); // User {intro: 'ts전문가입니다'}

Recap

  • **public**: (default)
  • **private**: 숨기고 extends한 class에도 사용 가능. 자식들 사용 불가능
  • **protected**: 숨기고 extends한 class에 사용 불가능. 자식들 사용 불가능
  • **static**: 숨기고 extends한 class에 사용 가능. 오직 class에서만 사용 가능.

숙제

1) 다음 x,y 속성의 특징을 설명해보십시오.

class User {
  private static x = 10;
  public static y = 20;
}

x와 y는 누가 쓸 수 있고, 어디서 수정할 수 있는지 이런 것들이요.

친구가 물어봤을 때 어떻게 답해줄 것입니까 아는 만큼 설명해봅시다.

➡️

  1. 필드값은 원래는 모든 User의 자식들에게 물려주는 속성이다. 하지만 x와 y에는 static 키워드가 붙었기 때문에 User.x 이런식으로만 접근해서 쓸 수 있다. User의 자식들은 x와 y를 쓸 수 없다.
  2. private static x는 오직 User class 내부에서만 수정할 수 있다. 밖에서는 수정할 수 없다. 오직 User class 내부에서 User.x = 변경할값 으로 입력하여 수정할 수 있다.
  3. public static y는 class 내부외부 상관없이 수정할 수 있다. User.y를 작성하여 수정 가능하다.
  4. protected z는 private 키워드와 유사하게 class 내부에서만 사용이 가능하다. 하지만 범위가 넓기 때문에 extends로 복사한 class 내부에서도 사용이 가능하다.

2) x 속성에 숫자를 더해주는 함수가 필요합니다.

class User {
  private static x = 10;
  public static y = 20;
}
User.addOne(3) //이렇게 하면 x가 3 더해져야함
User.addOne(4) //이렇게 하면 x가 4 더해져야함

저렇게 User.addOne() 쓸 때마다 x가 증가하는 함수는 어떻게 만들 수 있을까요?

그리고 x값에 뭐가 들었는지 확인하고싶으니까 x값을 콘솔창에 출력해주는 함수도 한번 만들어보십시오.

(조건) **private static x = 10;** 이거 코드 수정금지

➡️

class User {
    private static x = 10;
    public static y = 20;
    
    static addOne(num: number){
        User.x += num;
    }
    
    static printX(){
        console.log(User.x);
    }
}

User.addOne(3);
User.addOne(10);
User.printX();

3) 이런거 어떻게 만들게요

let 네모 = new Square(30, 30, 'red');
네모.draw()
네모.draw()
네모.draw()
네모.draw()

이렇게 네모.draw()를 할 때마다

index.html에 가로 30px, 세로 30px, 배경색이 'red' 의 <div> 박스가 무작위로 배치되어야합니다.

➡️

🕹️index.html

<body>
    <script src="index.js"></script>
</body>

🕹️index.js

class Square {
	constructor(public width :number, public height :number, public color :string){
        this.width = width;
        this.height = height;
        this.color = color;
    }
    draw(){
        let a = Math.random();
        let square = `<div style="position:relative;
        					top: ${a*400}px;
        					left: ${a*400}px;
        					width:${this.width}px;
        					height:${this.height}px;
        					background:${this.color}"></div>`
        document.body.insertAdjacentHTML('beforeend',square);
    }
}
let 네모 = new Square(30, 30, 'red');
네모.draw()
네모.draw()
네모.draw()
네모.draw()
  • constructor를 이용해서 새로뽑는 object 들은 width, height, color를 입력할 수 있게 만들었습니다.
  • 자식들은 draw()를 쓰면
    1. 0과 1사이의 무작위 숫자를 뽑습니다. 그걸 변수 a에 저장해둡니다.
    1. <div>를 디자인합니다. 근데 <div>박스의 폭, 높이, 색상은 constructor로 입력한 것들을 활용합니다.
    1. <div> 박스의 위치는 left, right 속성을 이용해서 0~400px 사이로 무작위로 배치합니다.
    1. insertAdjacentHTML 이런거 이용하면 원하는 곳에 html 추가가 가능합니다.
반응형