클래스 생성
class User {
constructor (
private firstName: string,
private lastName: string,
){}
}
class Person {
name: string; // 객체와 달리 쉼표가 아닌 것에 유의
constructor(name: string) {
this.name = name; // 이 클래스의 생성자로 처음 클래스가 만들어질 때 해당 구문이 실행됨
}
sayHello() {
return "안녕 " + this.name
} // 클래스 내부의 메서드(객체 내부의 함수)는 일반적인 함수와 유사하게 선언
}
let person = new Person("John");
TypeScript
복사
•
new를 사용하여 Person 클래스의 인스턴스 생성
◦
Person class의 필드는 name
◦
생성자 constructor
◦
메소드 say()가 있다.
•
클래스 안에 this.를 앞에 붙이면 클래스 필드를 의미
상속 클래스 (class * extends ^)
class Person {
name: string;
constructor(name: string) { //생성자
this.name = name;
}
greet() {
console.log(`안녕하세요, ${this.name}입니다.`);
}
}
class Student extends Person {
studentID: number; // 추가적인 데이터 한해서 작성
constructor(name: string, studentID: number) {
super(name); // 부모(상위) 클래스의 생성자를 호출
this.studentID = studentID;
}
greet() {
super.greet(); // 부모 클래스의 greet 메소드를 호출
console.log(`제 학번은 ${this.studentID}입니다.`);
}
// 하위 클래스에서 메소드를 다시 정의하는 것을 오버라이딩이
introduce(): void {
console.log(`이름은 ${this.name}이며 학번은 ${this.studentID}입니다.`);
} // 기존 클래스 생성자, 메서드 등을 변경할 수 있다.
}
const student = new Student('지민', 12345);
student.greet();
TypeScript
복사
•
클래스를 활용하여 객체를 만들 수 있지만, 또 다른 클래스도 만들 수 있음 => 상속
◦
OOP는 상속을 이용하여 존재하는 클래스를 확장해 새로운 클래스를 생성할 수 있다.
•
extends 키워드 사용
•
기존 클래스의 정보를 모두 살리고, 추가적인 정보 삽입 가능
•
파생된 클래스는 하위 클래스(subclass), 기초 클래스는 상위 클래스(superclass)라고 부른다. ⇒ 기존 거를 받고 새로운 것을 추가해서 새로운 클래스 생성
super()
1.
생성자 내에서: super()를 호출하면 부모 클래스의 생성자가 호출됩니다. 파생 클래스에서 생성자를 정의 할 때, 그 생성자 내에서 super()를 호출해야만 합니다. 이렇게 해야 부모 클래스의 생성자 로직이 올바르게 실행됩니다.
2.
메소드 내에서: super를 사용하여 부모 클래스의 메소드를 참조하거나 호출할 수 있습니다.
추상 클래스 (abstract class *)
abstract class User { // 추상 클래스
constructor (
private firstName: string,
private lastName: string,
protected nickName: string // protected로 해야 자식 클래스에서 접근 가능
){}
// 추상 메서드
abstract getNickNmame(): void; // 추상 메소드, 상속받은 클래스에서 반드시 정의/구현
//일반 매서드
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
} // 직접 인스턴스 생성 불가
class Player extends User {
getNickName(): void {
// 추상 클래스를 상속한 클래스는 추상 클래스의 추상 메소드를 반드시 구현
console.log(this.nickName);
}
getNick(): void {
// 추상 클래스를 상속한 클래스는 추상 클래스의 추상 메소드를 반드시 구현
console.log(this.nickName);
}
}
const honey = new Player("honey", "bee", "꿀벌");
const test = new User("honey", "bee", "꿀벌"); // Error, 추상 클래스는 객체 생성 불가
honey.getFullName();
TypeScript
복사
abstract class Department {
constructor(public name: string) {}
printName(): void {
console.log("Department name: " + this.name);
}
abstract printMeeting(): void; // 반드시 파생된 클래스에서 구현되어야 합니다.
}
class AccountingDepartment extends Department {
constructor() {
super("Accounting and Auditing"); // 파생된 클래스의 생성자는 반드시 super()를 호출해야 합니다.
}
printMeeting(): void {
console.log("The Accounting Department meets each Monday at 10am.");
}
generateReports(): void {
console.log("Generating accounting reports...");
}
}
let department: Department; // 추상 타입의 레퍼런스를 생성
department = new Department(); // 오류: 추상 클래스는 인스턴스화 불가
department = new AccountingDepartment(); // 추상이 아닌 하위 클래스를 생성하고 할당
department.printName();
department.printMeeting();
department.generateReports(); // 오류: 선언된 추상 타입에 메서드가 존재X
TypeScript
복사
•
추상 클래스는 다른 클래스들이 파생될 수 있는 기초 클래스이다.
•
상속을 강제하게 됨
•
작은 규모의 프로젝트에서는 거의 없음
•
직접 인스턴스화 할 수 없다.
•
abstract 키워드는 추상 클래스뿐만 아니라 추상 클래스 내에서 추상 메서드를 정의하는 데 사용된다.
•
추상 메소드는 클래스에 구현되어 있지 않고, 파생된 클래스에서 구현해야 한다.
•
추상 클래스(abstract class)는 하나 이상의 추상 메소드를 포함하며 일반 메소드도 포함할 수 있다.
•
추상 메소드는 내용이 없이 메소드 이름과 타입만이 선언된 메소드를 말하며 선언할 때 abstract 키워드를 사용한다. => 추상 클래스는 다른 클래스들이 파생될 수 있는 기초 클래스이다.
•
추상 클래스를 정의할 때는 abstract 키워드를 사용하며, 직접 인스턴스를 생성할 수 없고 상속만을 위해 사용된다. => abstract 클래스를 사용할 경우, 해당 클래스로 직접 객체를 만들 수 없다.
•
추상 클래스를 상속한 클래스는 추상 클래스의 추상 메소드를 반드시 구현하여야 한다.
복습
type Words = {
[key: string]: string
}
class Dict {
private words: Words;
constructor() {
this.words = {}
}
add(word: Word) {
if(this.words[word.term] === undefined)
this.words[word.term] = word.def;
}
def(term: string): string {
return this.words[term];
}
}
class Word {
constructor(
public term: string,
public def: string
) {}
}
const kimchi = new Word("kimchi", "한국의 음식");
const dict = new Dict();
dict.add(kimchi);
dict.def("kimchi");
TypeScript
복사
readonly
//class 멤버를 보여주고 싶지만 수정은 못하게 하고 싶을 때 사용
class Word {
constructor(
public readonly term: string,
public readonly def: string
) {}
}
const kimchi = new Word("kimchi", "한국의 음식");
kimchi.term = "xxx"; // Error
TypeScript
복사
static
class Word {
constructor(
public term: string,
public def: string
) {}
static hello() {
return "hello";
}
}
TypeScript
복사
추상 클래스 활용 디자인 패턴
추상 클래스 디자인 패턴 이용한 자동차 제조 사례
abstract class CarTemplate {
protected chassis: string;
protected body: string;
protected paint: string;
protected interior: string;
constructor() {
// Default constructor body can be left empty in TypeScript
}
// steps
abstract fixChassis(): void;
abstract fixBody(): void;
abstract paint(): void;
abstract fixInterior(): void;
// template method
manufactureCar(): void {
this.fixChassis();
this.fixBody();
this.paint();
this.fixInterior();
}
getChassis(): string {
return this.chassis;
}
setChassis(chassis: string): void {
this.chassis = chassis;
}
getBody(): string {
return this.body;
}
setBody(body: string): void {
this.body = body;
}
getPaint(): string {
return this.paint;
}
setPaint(paint: string): void {
this.paint = paint;
}
getInterior(): string {
return this.interior;
}
setInterior(interior: string): void {
this.interior = interior;
}
toString(): string {
// Using template literals for string building in TypeScript
return `Car [chassis=${this.chassis}, body=${this.body}, paint=${this.paint}, interior=${this.interior}]`;
}
}
TypeScript
복사
하위 클래스
class ClassicCar extends CarTemplate {
constructor() {
super();
}
fixChassis(): void {
console.log("Assembling chassis of the classical model");
this.chassis = "Classic Chassis";
}
fixBody(): void {
console.log("Assembling body of the classical model");
this.body = "Classic Body";
}
paint(): void {
console.log("Painting body of the classical model");
this.paint = "Classic White Paint";
}
fixInterior(): void {
console.log("Setting up interior of the classical model");
this.interior = "Classic interior";
}
}
TypeScript
복사
class SportsCar extends CarTemplate {
constructor() {
super();
}
fixChassis(): void {
console.log("Assembling chassis of the sports model");
this.chassis = "Sporty Chassis";
}
fixBody(): void {
console.log("Assembling body of the sports model");
this.body = "Sporty Body";
}
paint(): void {
console.log("Painting body of the sports model");
this.paint = "Sporty Torch Red Paint";
}
fixInterior(): void {
console.log("Setting up interior of the sports model");
this.interior = "Sporty interior";
}
}
TypeScript
복사
메인 함수
function main(): void {
const car: CarTemplate = new SportsCar();
car.manufactureCar();
if (car !== null) {
console.log("Below car delivered:");
console.log("======================================================================");
console.log(car.toString());
console.log("======================================================================");
}
}
main();
TypeScript
복사
참고 :