클래스는 값이면서 타입임
const Person = class {
name;
age;
married;
constructor(name:string,age:number,married:boolean){
this.name = name;
this.age = age;
this.married = married;
}
}
이렇게 씀
constructor에 멤버를 넣기 전에 한번 써줘야됨
멤버의 타입은 생략 가능함
멤버와 constructor는 짝이 맞아야 함
=> 그러니까 이 짝이 맞는 걸 타입체킹하는 거임. 더 엄격한 타입 검사를 원하면 implements 예약어를 쓰면 됨
interface Human {
name: string;
age : number;
married : boolean;
sayName():void;
}
/**sayName 없어서 오류 뱉음 */
class Person implements Human {
name;
age;
married;
constructor(name:string,age:number,married:boolean){
this.name = name;
this.age = age;
this.married = married;
}
}
대신 protected, private 접근 제어자는 interface에서 못 씀, 클래스에서만 가능함
// protected와 private 접근 제어자는 클래스에서만 사용 가능
class Parent {
name: string;
readonly age : number;
protected married: boolean;
private value: number;
constructor(name:string, age:number, married:boolean){
this.name = name;
this.age = age;
this.married = married;
this.value = 0;
}
changeAge(age:number){
/** 읽기 전용 속성이므로 'age'에 할당할 수 없습니다. */
this.age = age;
}
}
class Child extends Parent {
constructor(name:string, age:number, married:boolean){
/** 부모 호출 */
super(name,age,married)
}
sayName(){
console.log(this.name)
}
sayMarried(){
console.log(this.married)
}
sayValue(){
/** 'value' 속성은 private이며 'Parent' 클래스 내에서만 액세스할 수 있습니다. */
console.log(this.value)
}
}
/** 'married' 속성은 보호된 속성이며 'Parent' 클래스 및 해당 하위 클래스 내에서만 액세스할 수 있습니다. */
const {name, married} = new Child("one",22,true)
protected
자기 클래스, 자손 클래스 가능함
인스턴스는 사용 안 됨
private
자신 클래스에서만 사용 가능함
child, instance 사용 안 됨
?????? 그럼 #(private field) 이랑 private 차이는 뭘까
둘다 자기 클래스에서만 쓸 수 있음
다만 차이점은 책에서는 private은 자손 클래스에서 같은 이름으로 선언할 수 없다는 점이라는데
예제 따라해봐도 둘다 저런 에러는 안 나서 모르겠음...
다른 예시를 찾아본 결과
# 은 진정한 private이라고 소개하면서
이걸 예시로 듦
class MyClass {
#privateField = 10;
getPrivateField() {
return this.#privateField;
}
}
const obj = new MyClass();
console.log(obj.getPrivateField()); // 10
console.log(obj.#privateField);
private 필드는 TypeScript의 타입 검사 단계에서만 적용되고 컴파일된 JavaScript 코드에서는 프라이빗 특성을 잃게 됨
그러니까 타입스크립트가 빠진 런타임 때는 private 필드에 접근 가능한 상태임
# 는 자바스크립트에서도 프라이빗하게 유지됨
그러니까 private는 타입스크립트에서 제공한 접근자이기 때문에 런타임 때는 에러 못 잡고
#은 ecma, js 표준에서 도입된 문법이기 때문에 런타임에서 에러 잡을 수 있다는 게
둘 차이점임
책에서는
private 안 쓰고 # 쓴다고 함
public은 애초에 생략 가능하니 적지 않고
protected 수식어만 명시적으로 적어서 사용한다고 함
상속은 이렇게 한다면
그럼 오버라이딩은 어떻게 하지
타입스크립트에서도 class 오버라이딩 할 수 있음
ts.config에서 noImplicitOverride 설정 체크
class A {
eat(){console.log("냠")}
sleep(){console.log("쿨")}
}
class B extends A {
override sleep(){console.log('zzz')}
}
const a = new A()
const b = new B()
a.sleep()
// '쿨'
b.sleep()
//'zzz'
이렇게 쓰면 뭐가 오버라이딩 됐는지 적혀있어서 좋다고 함
추상 클래스
: 다른 클래스들이 상속받을 수 있는 클래스를 정의하지만, 직접 인스턴스화할 수 없는 클래스
일단... 다른 클래스들이 상속 받아 쓸 수 있도록 만들어짐
common Class 같은 건가? 싶은데 그건 아님...
꼭 만들어야하는 이름의 메서드 이름을 정의해놓고 상속 받은 하위 class들이 그걸 구체적으로 만들어서 써야함
자리만 만들어주는 느낌

abstract class Animal {
abstract makeSound(): void; // 자리만 만들어둠, 실제 구현은 자식 클래스에서
}
class Dog extends Animal {
makeSound() {
console.log("Woof! Woof!"); // Dog 클래스의 소리
}
}
class Cat extends Animal {
makeSound() {
console.log("Meow!"); // Cat 클래스의 소리
}
}
타입스크립트도 똑같은 걸 체크함
부모의 makeSound를 만들었는지 여부를 봄
abstract 클래스는 타입스크립트 문법이지만 자바스크립트 코드로 변환됨
abstract class Animal {
abstract makeSound(): void; // 추상 메서드
move(): void {
console.log("Moving along...");
}
}
class Dog extends Animal {
makeSound() {
console.log("Woof! Woof!");
}
}
이렇게 생겼다면
class Animal {
move() {
console.log("Moving along...");
}
}
class Dog extends Animal {
makeSound() {
console.log("Woof! Woof!");
}
}
const dog = new Dog();
dog.makeSound(); // "Woof! Woof!"
dog.move(); // "Moving along..."
이렇게 바뀜
'TIL' 카테고리의 다른 글
타입스크립트 - infer (0) | 2024.08.18 |
---|---|
타입스크립트 - enum (0) | 2024.08.18 |
타입스크립트 공변성, 반공변성 (0) | 2024.08.11 |
타입스크립트 오버로딩 (0) | 2024.08.11 |
싱글톤 (0) | 2024.08.04 |
댓글