TypescriptにおけるClassの活用方法を確認します。ES2015のClass機能はprivateメンバを定義できないなど機能の不十分さを感じます。TypescriptのClass機能は、ES2015のClass機能より充実しています。
目次
クラスの導入
( property, constructor, method )
まずは、簡単なクラスで動作確認します。property
constructor
method
を定義してます。
class Animal {
// property
name: string;
old: number;
// constructor
constructor(name: string, old: number) {
this.name = name;
this.old = old;
}
// method
showName() {
console.log(this.name)
}
showOld() {
console.log(this.old)
}
}
export default Animal
import Animal from './animal'
const animal = new Animal('ジョン', 22);
animal.showName(); // ジョン
animal.showOld(); // 22
継承
( extends, super )
継承の動作確認をします。
class Animal {
name: string;
old: number;
constructor(name: string, old: number) {
this.name = name;
this.old = old;
}
showName() {
console.log(this.name)
}
showOld() {
console.log(this.old)
}
}
class Dog extends Animal {
weight: number;
constructor(name: string, old: number, weight: number) {
super(name, old);
this.weight = weight;
}
showWeight() {
console.log(this.weight)
}
}
const dog = new Dog('ジョン', 3, 20);
dog.showName(); // ジョン
dog.showOld(); // 3
dog.showWeight(); // 20
extends
で継承します。super
で継承元のconstructorを呼び出しています。
アクセス修飾子
( public, private, protected, readonly )
下記アクセス修飾子のパターンを動作確認します。
public
- デフォルトなので、明示しない場合も
public
になります。
- デフォルトなので、明示しない場合も
private
- 自インスタンスのみアクセスできます。
protected
- 継承先classのインスタンスでもアクセスできます。
readonly
public readonly
となります。
private readonly
readonly
は、宣言時、またはコンストラクタ内で初期化する必要があります。Parameter properties
という方法で設定することもできます。
class Base {
public a: number;
private b: number;
protected c: number;
private readonly d: number = 40;
constructor(
a: number,
b: number,
c: number,
readonly e: number // Parameter properties
) {
this.a = a;
this.b = b;
this.c = c;
}
showA() {
console.log(this.a);
this.a = 1;
}
showB() {
console.log(this.b);
this.b = 1;
}
showC() {
console.log(this.c);
this.c = 1;
}
showD() {
console.log(this.d);
// readonlyのためError
// this.d = 1;
}
showE() {
console.log(this.e);
// readonlyのためError
// this.e = 1;
}
}
class Child extends Base {
showA() {
console.log(this.a);
this.a = 1;
}
showB() {
// privateのためError(Private member is not accessible)
// console.log(this.b);
// this.b = 1;
}
showC() {
console.log(this.c);
this.c = 1;
}
showD() {
// private readonlyのためError
// console.log(this.d);
// this.d = 1;
}
showE() {
console.log(this.e);
// readonlyのためError
// this.e = 1;
}
}
const child = new Child(10, 20, 30, 50);
console.log(child.a); // 10
// privateのためError
// console.log(child.b);
// protectedのためError
// console.log(child.c);
// private readonlyのためError
// console.log(child.d);
console.log(child.e); // 50
Accessors
( set, get )
class Animal {
private _name: string;
get name(): string {
return this._name;
}
set name(newName: string) {
console.log(`Set name: ${newName}`);
this._name = newName;
}
}
const animal = new Animal();
console.log(animal.name);
animal.name = 'abcdef';
console.log(animal.name);
Accessorsは、targetが ECMAScript 5
以上でないと利用できません。
$ tsc -t ES5 accessors.ts
$ node accessors.js
undefined
Set name: abcdef
abcdef
Static
( 静的メンバ )
class StaticTest {
static count = 0;
constructor(private name: string) {
StaticTest.count++;
}
public instanceMethod() {
return `name: ${this.name} count: ${StaticTest.count}`;
}
static staticMethod() {
return StaticTest.count;
}
}
const staticTest1 = new StaticTest('xxxxx');
console.log(staticTest1.instanceMethod()); // name: xxxxx count: 1
console.log(StaticTest.count); // 1
console.log(StaticTest.staticMethod()); // 1
const staticTest2 = new StaticTest('yyyyy');
console.log(staticTest2.instanceMethod()); // name: yyyyy count: 2
console.log(StaticTest.count); // 2
console.log(StaticTest.staticMethod()); // 2
静的メンバには、クラス名.静的メンバ名
でアクセスします。
Abstract
( 抽象クラス )
abstract class AbstractClass {
protected constructor(private name: string, protected old: number) {
}
showInfo(): void {
console.log(`name: ${this.name}, ${this.showDetail()}`);
}
protected abstract showDetail(): string;
}
class ExtendedClass extends AbstractClass {
constructor(name: string, old: number, private weight: number) {
super(name, old);
}
showDetail(): string {
return `old: ${this.old}, weight: ${this.weight}`;
}
}
const extendedClass = new ExtendedClass('ジョン', 3, 20);
extendedClass.showInfo(); // name: ジョン, old: 3, weight: 20
- 抽象クラスは抽象メソッドを持ちます。
- 抽象クラスに
abstract
をつけます。 - 抽象メソッドに
abstract
をつけます。
- 抽象クラスに
- 抽象クラスを継承したクラスは、抽象メソッドを実装する必要があります。