본문 바로가기

JS/TypeScript

타입스크립트 튜토리얼 class

타입스크립트는 객체 지향 자바스크립트다. 타입스크립트는 클래스, 인터페이스와 같은 객체 지향 프로그래밍 특성을 지원한다. 객체 지향 프로그래밍에서 클래스는 객체를 생성하기 위한 청사진이다. 클래스는 객체를 위해 데이터를 캡슐화한다. 타입스크립트는 클래스라는 개념을 지원한다. ES5 이전에는 클래스를 지원하지 않았다. 타입스크립트는 이런 특징을 ES6로부터 얻었다.


클래스 생성

class 키워드를 써서 클래스를 선언한다.


문법

class class_name { 
   //class scope 
}


클래스 키워드는 클래스 이름 앞에 온다. 


클래스 정의는 다음을 포함할 수 있다.

fields : 필드는 클래스 안에서 선언되는 모든 변수다. 필드는 객체에 관련된 데이터를 나타낸다.

constructors : 클래스의 객체를 위한 메모리 할당을 한다.

functions : 객체가 해야 할 동작을 나타낸다. 때때로 메서드라고 부르기도 한다.


이런 구성물들을 클래스의 데이터 멤버라고 한다.


타입스크립트에서의 Person 클래스를 고려해보면

class Person {
}


자바스크립트로 컴파일하면

var Person = (function () {
   function Person() {
   }
   return Person;
}());


클래스 선언

class Car { 
   //field 
   engine:string; 
 
   //constructor 
   constructor(engine:string) { 
      this.engine = engine 
   }  

   //function 
   disp():void { 
      console.log("Engine is  :   "+this.engine) 
   } 
}

Car 클래스를 선언한다. 클래스는 engine이라는 필드 이름을 가진다. 필드를 선언할 때는 var 키워드는 쓰이지 않는다. 클래스를 위한 생성자를 선언한다.

생성자는 클래스의 변수 초기화를 담당하는 클래스의 특별한 함수이다. 타입스크립트는 생성자를 constructor 키워드를 써서 정의한다. 생성자는 함수이자 매개변수를 갖는다.

this 키워드는 클래스의 현재 인스턴스를 가리킨다. 인자 이름과 클래스의 필드의 이름은 같다. 모호함을 피하기 위해 클래스의 필드는 this 키워드가 접두어로 붙는다.

disp()는 간단한 함수 정의다. function 키워드는 쓰이지 않는다.


자바스크립트 컴파일

var Car = (function () {
   //constructor
   function Car(engine) {
      this.engine = engine;
   }
	
   //function
   Car.prototype.disp = function () {
      console.log("Engine is  :   " + this.engine);
   };
   return Car;
}());


인스턴스 객체 생성하기

클래스의 인스턴스를 생성하기 위해, new 키워드 다음에 클래스 이름을 쓴다.


문법

var object_name = new class_name([ arguments ])


new 키워드는 초기화를 담당한다.

표현식의 오른쪽이 생성자를 호출한다. 생성자는 인자가 있으면 값을 전달해야 한다.


클래스 초기화

var obj = new Car("Engine 1")


속성과 함수에 접근하기

클래스의 속성과 함수는 객체를 통해 접근될 수 있다. period라고 하는 '.' 점 표기를 해서 클래스의 데이터 멤버들에 접근할 수 있다.

//accessing an attribute 
obj.field_name 

//accessing a function 
obj.function_name()


클래스 선언, 객체 생성, 접근

class Car { 
   //field 
   engine:string; 
   
   //constructor 
   constructor(engine:string) { 
      this.engine = engine 
   }  
   
   //function 
   disp():void { 
      console.log("Function displays Engine is  :   "+this.engine) 
   } 
} 

//create an object 
var obj = new Car("XXSY1")

//access the field 
console.log("Reading attribute value Engine as :  "+obj.engine)  

//access the function
obj.disp()


자바스크립트 컴파일

var Car = (function () {
   //constructor
   function Car(engine) {
      this.engine = engine;
   }
	
   //function
   Car.prototype.disp = function () {
      console.log("Function displays Engine is  :   " + this.engine);
   };
   return Car;
}());

//create an object
var obj = new Car("XXSY1");

//access the field
console.log("Reading attribute value Engine as :  " + obj.engine);

//access the function
obj.disp();

출력

Reading attribute value Engine as :  XXSY1 
Function displays Engine is  :   XXSY1


클래스 상속

타입스크립트는 상속 개념을 지원한다. 상속은 존재하는 클래스로부터 새로운 클래스를 생성하는 프로그램의 기능이다. 새로운 클래스를 생성하기 위해 확장된 클래스를 부모 클래스/슈퍼 클래스라고 부른다. 새롭게 생성된 클래스는 자식/서브 클래스라고 불린다.


클래스는 extends 키워드를 써서 다른 클래스로부터 확장한다. 자식 클래스는 부모 클래스로부터 프라이빗 멤버와 생성자를 제외한 모든 속성과 메서드를 상속한다.


문법

class child_class_name extends parent_class_name


그러나 타입스크립트는 다중 상속을 지원하지 않는다.


클래스 상속

class Shape { 
   Area:number 
   
   constructor(a:number) { 
      this.Area = a 
   } 
} 

class Circle extends Shape { 
   disp():void { 
      console.log("Area of the circle:  "+this.Area) 
   } 
}
  
var obj = new Circle(223); 
obj.disp()

자바스크립트 컴파일

var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Shape = (function () {
   function Shape(a) {
      this.Area = a;
   }
   return Shape;
}());

var Circle = (function (_super) {
   __extends(Circle, _super);
   function Circle() {
      _super.apply(this, arguments);
   }
	
   Circle.prototype.disp = function () { 
      console.log("Area of the circle:  " + this.Area); 
   };
   return Circle;
}(Shape));

var obj = new Circle(223);
obj.disp();

출력

Area of the Circle: 223

위 예는 Shape 클래스를 선언한다. 클래스는 Circle 클래스에서 확장되었다. Circle 클래스와 Shape 클래스 간에 상속 관계가 있기 때문에 Car 클래스는 암묵적으로 부모 클래스의 속성인 area에 접근한다.


상속은 다음과 같이 분류할 수 있다.

single : 모든 클래스는 하나의 부모클래스에서 최대로 확장할 수 있다.

multiple : 클래스는 여러 클래스로부터 상속할 수 있다. 타입스크립트는 다중 상속을 지원하지 않는다.

multiple-level : 다음 예는 어떻게 다단계 상속이 동작하는지 보여준다.

class Root { 
   str:string; 
} 

class Child extends Root {} 
class Leaf extends Child {} //indirectly inherits from Root by virtue of inheritance  

var obj = new Leaf(); 
obj.str ="hello" 
console.log(obj.str)

Leaf 클래스는 다단계 상속에 의해 Root와 Child 클래스로부터 속성을 도출한다.


자바스크립트 컴파일

var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

var Root = (function () {
   function Root() {
   }
   return Root;
}());

var Child = (function (_super) {
   __extends(Child, _super);
   function Child() {
      _super.apply(this, arguments);
   }
   return Child;
}(Root));

var Leaf = (function (_super) {
   __extends(Leaf, _super);
   function Leaf() {
      _super.apply(this, arguments);
   }
   return Leaf;
}(Child));

var obj = new Leaf();
obj.str = "hello";
console.log(obj.str);

출력

hello

타입스크립트 : 클래스 상속과 메서드 오버라이딩

메서드 오버라이딩은 자식 클래스가 슈퍼클래스의 메서드를 재정의하는 메커니즘이다.

class PrinterClass { 
   doPrint():void {
      console.log("doPrint() from Parent called…") 
   } 
} 

class StringPrinter extends PrinterClass { 
   doPrint():void { 
      super.doPrint() 
      console.log("doPrint() is printing a string…")
   } 
} 

var obj = new StringPrinter() 
obj.doPrint()


super키워드는 클래스의 부모를 바로 나타내기 위해 쓴다. 그 키워드는 변수, 속성, 메서드의 슈퍼 클래스 버전을 인용하기 위해 사용될 수 있다. 13번째 줄은 doWork() 함수의 부모클래스 버전을 호출한다.


자바스크립트 컴파일

var __extends = (this && this.__extends) || function (d, b) {
   for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
   function __() { this.constructor = d; }
   d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

var PrinterClass = (function () {
   function PrinterClass() {
   }
   PrinterClass.prototype.doPrint = function () { 
      console.log("doPrint() from Parent called…"); 
   };
   return PrinterClass;
}());

var StringPrinter = (function (_super) {
   __extends(StringPrinter, _super);
	
   function StringPrinter() {
      _super.apply(this, arguments);
   }
	
   StringPrinter.prototype.doPrint = function () {
      _super.prototype.doPrint.call(this);
      console.log("doPrint() is printing a string…");
   };
	
   return StringPrinter;
}(PrinterClass));

var obj = new StringPrinter();
obj.doPrint();

출력

doPrint() from Parent called… 
doPrint() is printing a string…


static 키워드

static 키워드는 클래스의 데이터 멤버에 적용할 수 있다. static 변수는 프로그램이 실행을 종료할 때까지 값을 유지한다. 정적 멤버들은 클래스 이름에 의해 참조된다.


class StaticMem {  
   static num:number; 
   
   static disp():void { 
      console.log("The value of num is"+ StaticMem.num) 
   } 
} 

StaticMem.num = 12     // initialize the static variable 
StaticMem.disp()      // invoke the static method

자바스크립트 컴파일

var StaticMem = (function () {
   function StaticMem() {
   }
	
   StaticMem.disp = function () {
      console.log("The value of num is" + StaticMem.num);
   };
	
   return StaticMem;
}());

StaticMem.num = 12;     // initialize the static variable
StaticMem.disp();      // invoke the static method

출력

The value of num is 12

instanceof 연산자

instanceof 연산자는 만약 객체가 지정된 타입에 속한다면 true를 반환한다.

class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log(" obj is an instance of Person " + isPerson);

자바스크립트 컴파일

var Person = (function () {
   function Person() {
   }
   return Person;
}());

var obj = new Person();
var isPerson = obj instanceof Person;
console.log(" obj is an instance of Person " + isPerson);

출력

obj is an instance of Person True 


데이터 은닉

클래스는 데이터 멤버의 가시성을 다른 클래스의 멤버에게 제어할 수 있다. 이런 능력을 데이터 은닉 또는 캡슐화라고 한다.


객체 지향은 캡슐화 개념을 구현하기 위해 접근 수정자 또는 접근 지정자 개념을 사용한다. 접근 지정자/수정자는 정의 클래스 외부에서 클래스의 데이터 멤버에 대한 가시성을 정의한다.


타입스크립트에 의해 지원되는 접근 수정자

S.No.Access Specifier & Description
1.

public

A public data member has universal accessibility. Data members in a class are public by default.

public 데이터 멤버는 어디서나 접근 가능하다. 클래스의 데이터 멤버는 기본적으로 public이다.

2.

private

Private data members are accessible only within the class that defines these members. If an external class member tries to access a private member, the compiler throws an error.

private 데이터 멤버는 오직 멤버들이 정의된 클래스 안에서만 접근 가능하다. 외부의 클래스 멤버가 private 멤버에 접근을 시도하면 컴파일러는 에러를 던진다.

3.

protected

A protected data member is accessible by the members within the same class as that of the former and also by the members of the child classes.

protected 데이터 멤버는 같은 클래스에 속하는 멤버와 자식 클래스의 멤버에서 접근할 수 있다.

class Encapsulate { 
   str:string = "hello" 
   private str2:string = "world" 
}
 
var obj = new Encapsulate() 
console.log(obj.str)     //accessible 
console.log(obj.str2)   //compilation Error as str2 is private

클래스는 두가지 문자열 속성 str, str2를 가진다. str은 public, str2는 private이다. 클래스는 초기화되었다. 예는 private 속성 str2가 선언된 클래스의 바깥에서 접근되었기 때문에 컴파일 타임 에러를 반환한다.


클래스와 인터페이스

interface ILoan { 
   interest:number 
} 

class AgriLoan implements ILoan { 
   interest:number 
   rebate:number 
   
   constructor(interest:number,rebate:number) { 
      this.interest = interest 
      this.rebate = rebate 
   } 
} 

var obj = new AgriLoan(10,1) 
console.log("Interest is : "+obj.interest+" Rebate is : "+obj.rebate )

AgriLoan 클래스는 Loan 인터페이스를 구현한다. 이것의 멤버로서 interest 속성을 포함하기 위해 클래스에 바인딩된다.


자바스크립트 컴파일

var AgriLoan = (function () {
   function AgriLoan(interest, rebate) {
      this.interest = interest;
      this.rebate = rebate;
   }
   return AgriLoan;
}());

var obj = new AgriLoan(10, 1);
console.log("Interest is : " + obj.interest + " Rebate is : " + obj.rebate);

출력

Interest is : 10 Rebate is : 1


https://www.tutorialspoint.com/typescript/typescript_classes.htm