타입스크립트에서 다음과 같은 코드를 실행하면
class Player {
constructor(
private firstNmae:string,
private lastNmae:string,
public nickname:string
) {}
}
const allong = new Player("allong", "las", "재홍");
자바스크립트에서는 다음과 같이 실행된다.
class Player {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.nickname = nickname;
}
}
const allong = new Player("allong", "las", "재홍");
그리고 public 속성은 외부에서 직접 접근이 가능하지만, private 속성은 외부에서 직접 접근이 불가능하므로 컴파일 과정에서 오류를 나타낸다.
abstract class User {
constructor(
private firstNmae:string,
private lastNmae:string,
public nickname:string
) {}
}
class Player extends User {}
추상클래스는 다른 클래스가 상속받을 수 있는 클래스이다. 하지만 이 클래스는 직접 새로운 인스턴스를 만들 수는 없다. 가령 new User()
의 형태로 새로운 클래스를 생성할 수는 없다. 다시 한번 말하자면 추상 클래스는 오직 다른 곳에서 상속 받을 수만 있는 클래스이다.
위의 코드에서 const allong = new Player("allong", "las", "재홍")
으로 새로운 클래스를 생성하여 allong.nickname
으로 여전히 접근할 수 있다.
abstract class User {
constructor(
private firstNmae:string,
private lastNmae:string,
public nickname:string
) {}
getFullName() {
return `${this.firstName} ${this.lastName}`
}
}
class Player extends User {}
const allong = new Player("allong", "las", "재홍")
이 경우, allong.getFullName()
과 같이 사용할 수 있다. 만약 getFullName메소드 앞에 private
이 붙으면 더이상 작동하지 않게 된다. 즉, private과 public은 속성 뿐 아니라 메서드에도 작동한다.
한편 추상 클래스 안에서는 추상 메서드를 만들 수가 있는데 메서드를 구현해서는 안 되고 대신에 메서드의 call signature만을 적어야 한다.
가령 위의 사례에서 nickname 속성을 private으로 하고, nickname을 얻는 추상 메서드를 만든다고 가정해보자.
abstract class User {
constructor(
private firstNmae:string,
private lastNmae:string,
private nickname:string
) {}
abstract getNickName():void
getFullName() {
return `${this.firstName} ${this.lastName}`
}
}
class Player extends User {}
const allong = new Player("allong", "las", "재홍")
위와 같이 getNickName이라는 추상 메서드는 call signature만을 가지고 있고, 구현은 되어 있지 않다. 이러면 타입스크립트는 Player라는 class에 대해서 getNickName이라는 메서드를 구현해야 한다고 알려주게 된다.
따라서 User라는 추상 클래스를 상속받는 Player에서 메서드를 구현해주어야 한다.
abstract class User {
constructor(
private firstNmae:string,
private lastNmae:string,
private nickname:string
) {}
abstract getNickName():void
getFullName() {
return `${this.firstName} ${this.lastName}`
}
}
class Player extends User {
getNickName() {
console.log(this.nickname)
}
}
const allong = new Player("allong", "las", "재홍")
여기에서 Player 클래스의 console.log(this.nickname)은 동작하지 않는데 nickname이 private으로 지정되었기 때문이다. property를 private으로 만든다면, 해당 클래스를 상속하였을지라도 해당 property에 접근할 수 없다. field를 보호하는 방식에 private과 public만 있는 것이 아니고, protected도 있다. private으로 보호되고 있는 property들은 인스턴스 밖에서 접근할 수가 없고, 자식 클래스에서도 접근할 수 없다. 만약 해당 필드가 외부로부터는 보호받지만 다른 자식 클래스에서 사용되기를 원한다면 protected를 사용하여야 한다.