Typescript Handbook / Developer’s Record 를 참고했습니다.
기본
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return `안녕 ${this.greeting}`;
}
}
let 병인이: Greeter = new Greeter("만나서 반가워");
console.log(병인이.greet()); // 안녕 만나서 반가워
상속
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(distance: number) {
console.log(`${this.name} moved ${distance}`);
}
}
class Snake extends Animal {
constructor(name: string) {
super(name);
}
move(distance: number = 15) {
console.log(`스....~...스윽... 거리며 ${distance}m 움직였다`);
super.move(distance)
}
}
class Horse extends Animal {
constructor(name: string) {
super(name);
}
move(distance: number = 20) {
console.log(`히히힝히잉히이이잉히잉 거리며 ${distance}m 움직였다`);
super.move(distance);
}
}
let 나뱀: Snake = new Snake("걍뱀");
let 나말: Horse = new Horse("양말");
나말.move(22);
// 히히힝히잉히이이잉히잉 거리며 22m 움직였다
// 양말 moved 22
접근 제어
public
class Animal {
public name: string;
public constructor(name: string) {
this.name = name;
}
public move(distance: number) {
console.log(`${this.name} moved ${distance}`);
}
}
protected
class Person {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
class Employee extends Person {
public department: string;
constructor(name: string, department: string) {
super(name);
this.department = department;
}
introduce() {
console.log(`Hello, my name is ${this.name} and I work in ${this.department}`);
}
}
let employee: Employee = new Employee("윤병인", "개발부서");
employee.introduce(); // Hello, my name is 윤병인 and I work in 개발부서
Person을 바로 intialize하면 name에 접근 할 수 없다.
class Person {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
let person: Person = new Person("윤병인");
person.name; // error : Property 'name' is protected and only accessible within class 'Person' and its subclasses.ts(2445)
private
class Animal {
name: string;
private sex: string;
constructor(name: string, sex: string) {
this.name = name;
this.sex = sex;
}
move(distance: number) {
console.log(`${this.name} moved ${distance}m`);
}
}
let dog: Animal = new Animal("강아쥐", "수컷");
console.log(dog.name);
console.log(dog.sex); // Property 'sex' is private and only accessible within class 'Animal'
호환문제
class Animal {
public name: string;
constructor(name: string) {
this.name = name;
}
}
class Paper {
public name: string;
constructor(name: string) {
this.name = name;
}
}
let animal: Animal = new Animal("걍동물");
let paper: Paper = new Paper("걍종이");
animal = paper;
console.log(animal.name); // 걍종이
구조가 같으면 할당이 된다!
class Animal {
public name: string;
constructor(name: string) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name: string) {
super(name);
}
bark() {
console.log("멍! 멍! 멍! 멍!");
}
}
let animal: Animal = new Animal("걍동물");
let dog: Dog = new Dog("개자슥");
animal = dog;
console.log(animal.name); // 개자슥
animal.bark(); // error : Property 'bark' does not exist on type 'Animal'.
하지만, 그렇다고 없던걸 쓸 수 있는건 아니다. 마치 Typecasting느낌이랄까..
Readonly
class Octopus {
name: string;
readonly numberOfLegs: number = 8;
constructor(name: string) {
this.name = name;
}
}
let dad: Octopus = new Octopus("우리아부지");
console.log(dad.name);
console.log(dad.numberOfLegs);
dad.numberOfLegs = 2; // error : Cannot assign to 'numberOfLegs' because it is a read-only property
Parameter Property
class Octopus {
readonly numberOfLegs: number = 8;
constructor(public name: string, private secret: string) {}
}
let dad: Octopus = new Octopus("우리아부지", "대머리");
console.log(dad.name); // 우리아부지
이거 편하다. 인자값 앞에 접근제한자를 붙이면 된다.
Getter/Setter
let passcode = "secret passcode";
class Employee {
constructor(private _fullName: string) {}
get fullName(): string {
console.log("you're trying to get fullName");
return this._fullName;
}
set fullName(newName: string) {
console.log(`you're trying to set fullName as ${newName}`);
if (passcode && passcode == "secret passcode") {
this._fullName = newName;
} else {
console.log("Error : check your passcode first");
}
}
}
let employee: Employee = new Employee("Jin Macho");
employee.fullName // you're trying to get fullName
employee.fullName = "Bob Smith"; // you're trying to set fullName as Bob Smith
그닥 쓸모있어 보이지는 않는다.
Static
class Grid {
static origin = {x: 0, y: 0};
constructor(public scale: number) {}
calculateDistanceFromOrigin(point: {x: number, y: number}) {
let xDist = (point.x - Grid.origin.x);
let yDist = (point.y - Grid.origin.y);
return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
}
}
let grid: Grid = new Grid(1.0);
console.log(grid.calculateDistanceFromOrigin({x: 10, y: 20})); // 22.360679774997898
Abstract
abstract class Animal {
abstract makeSound(): void;
move(): void {
console.log("Move ... Move !");
}
}
let animal: Animal = new Animal(); // error : Cannot create an instance of an abstract class.
그 자체로 initialize는 안된다.
abstract class Department {
constructor(public name: string) {}
printName(): void {
console.log(`Department name: ${this.name}`);
}
abstract printMeeting(): void;
}
class AccountingDepartment extends Department {
constructor(name: string) {
super(name);
}
printMeeting(): void {
console.log("Meeting in on 10am");
}
generateReports() {
console.log("Generating Reports");
}
}
let depatment: AccountingDepartment = new AccountingDepartment("ACD");
depatment.printName(); // ACD
depatment.printMeeting(); // Meeting in on 10am
abstract keyword가 붙은 거는 꼭 상속받는 sub class에서 정의해줘야한다.
생성자함수
너무 길어서 다음번에 해야겠다.