TypeScript #5 Class
class Car{
color:string;
// constructor(readonly color: string){
// constructor(public color: string){
constructor(color: string){
this.color = color;
}
start(){
console.log("start");
}
}
위와 같은 방법으로 color 프로퍼티의 타입을 정확히 명시해주는 방법으로 명시적인걸 좋아하는 타입스크립트의 컴파일 에러를 방지할 수 있다. 그리고,
주석 처리한 방법중 하나인 public 접근 제한자를 사용하여 'color' 프로퍼티를 선언과 동시에 생성자의 매개변수로 선언.
constructor(public color: string)
이러한 경우, 타입스크립트 컴파일러가 자동으로 생성자 매개변수에 대응하는 클래스 프로퍼티를 만들어주며, 해당 프로퍼티의 타입은 자동으로 추론된다
추가로 public, protected, private에 대해서 좀 더 자세히 설명하자면
class Person {
public name: string;
public age: number;
protected salary: number;
constructor(name: string, age: number, salary: number) {
this.name = name;
this.age = age;
this.salary = salary;
}
}
class Employee extends Person {
getSalary() {
return this.salary; // 접근 가능
}
}
const person = new Person('John', 30, 5000);
console.log(person.name); // 접근 가능
console.log(person.age); // 접근 가능
console.log(person.salary); // 접근 불가능
public과 protected의 가장 큰 차이점은 접근 가능한 범위입니다. public 멤버는 클래스 외부에서도 직접 접근이 가능하며, protected 멤버는 클래스 외부에서 직접 접근할 수 없고 해당 클래스를 상속받은 하위 클래스에서만 접근 가능합니다.
아래 예제 코드를 보면 public 멤버인 name과 age는 클래스 외부에서도 직접 접근이 가능합니다. 반면 protected 멤버인 salary는 Person 클래스를 상속받은 Employee 클래스에서는 직접 접근할 수 있지만, 클래스 외부에서는 접근할 수 없습니다.
constructor(readonly color: string)
readonly 키워드를 사용한 경우는 클래스 인스턴스가 생성된 후 변경되지 않으므로 초기화한 뒤의 값을 유지할 것이다 그래서 타입에 관련된 문제가 발생할 여지가 없기 때문에, 컴파일 에러를 띄우지 않는다.
static class 변수
class Car{
//접근제한자 private를 표현하는 또다른 방법은 #을 붙이는 방법이다.
// #name:string = "car";
readonly name:string ="car";
color:string;
static wheels = 4;
constructor(color: string, name:string){
this.color = color;
this.name = name;
}
start(){
console.log("start");
console.log(this.name);
/*
static 변수 wheels는 클래스 변수이므로 인스턴스 객체에 속하지 않습니다.
따라서 this 키워드를 사용하여 접근할 수 없습니다.
this는 인스턴스 객체를 참조하기 때문입니다.
*/
console.log(Car.wheels);
}
}
Abstract class
//추상 클래스
abstract class Car{
color:string;
static wheels = 4;
constructor(color: string){
this.color = color;
}
start(){
console.log("start");
}
abstract doSometing():void;
}
// const car = new Car("red");
class Bmw extends Car{
constructor(color:string){
super(color);
}
doSometing(){
alert(3);
}
}
const z4 = new Bmw("black");
추상 클래스는 일반 클래스와 마찬가지로 객체를 생성할 수 있지만, 추상 메서드를 하나 이상 포함하는 클래스입니다. 추상 메서드는 메서드의 시그니처(메서드 이름, 매개 변수, 반환 값 등)만 선언되고, 구현부는 없습니다.
따라서 추상 클래스는 단순히 추상 메서드를 포함하고 있으므로 객체를 생성할 수 없습니다. 대신 추상 클래스를 상속하는 하위 클래스에서 추상 메서드를 반드시 구현해야합니다.
위 코드에서 Car 클래스는 doSomething() 메서드를 추상 메서드로 선언하고 있습니다. 그리고 Bmw 클래스는 Car 클래스를 상속받고, doSomething() 메서드를 구현하여 추상 메서드를 구현했습니다.
즉, Car 클래스에서 정의된 추상 메서드 doSomething()를 하위 클래스에서 구현해야 합니다. 이렇게 하위 클래스에서 구현해야하는 메서드를 명시하면, 코드의 가독성을 높일 수 있습니다. 또한, 추상 클래스는 다형성을 구현하는데 유용하게 사용됩니다.