Type Script-Class es

9413 ワード

概要
JavaScript言語は、関数とプロトタイプチェーン継承機構に基づいて再利用可能なコンポーネントを構築する.これはOO側のプログラミングにとって不器用に見える.次世代のJavaScript標準ECMAScript 6は、classベースのOOデザインを提供してくれます.Type Scriptにおいてもこのような方式を使用することができます.Type Scriptは現在の大多数のブラウザで許可されている普通のJavascriptコードをコンパイルしますので、ECMAScript 6の到来を待つ必要はありません.
クラス
まず、class-baseに関する実例を見ます.
class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

var greeter = new Greeter("world");
  
このような文法は私たちが前にc奄、java言語で見たのと似ています.ここでは,greetingの特性,構造関数,およびgreetの方法を含むGreerクラスを宣言した.
例の「this」のキーワードに注目したかもしれません.
最後の行で「new」というキーワードを使ってGreerのオブジェクト例を作成しました.これはオブジェクトの例を新規作成し、先に定義したコンストラクタを呼び出してこのオブジェクトを初期化します.
引き継ぐ
Type Scriptでは私たちがよく使うOOデザインモデルが使えます.もちろん、OO設計の基本的なものは、タイプの継承(存在するクラスを継承し、存在する論理を多重化する)であり、以下の例は、クラス継承の例である.
class Animal {
    name:string;
    constructor(theName: string) { this.name = theName; }
    move(meters: number) {
        alert(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move() {
        alert("Slithering...");
        super.move(5);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move() {
        alert("Galloping...");
        super.move(45);
    }
}

var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);
  
この事例ではType ScriptのOO継承方式を示しています.他の言語と似ています.Type Scriptでは「extends」というキーワードを使って種類の継承関係を表します.ここでは、「Horse」と「Snake」は、「Animal」に継承されたサブクラスの実現が見られます.
ケースでは、父親タイプを書き換える方法も示しており、ここでは「スネーク」と「Horse」はそれぞれ「move」方法を作成して、親タイプの「Animal」の「move」方法を書き直し、「super」キーワードとともに親タイプを呼び出す方法である.
Private/Publicアクセス制限
Publicはデフォルトです.
上記の例では、クラスのメンバーのアクセスレベルを「public」というキーワードで説明していないことに気づいたかもしれません.C〓〓〓のこの種類の言語の中で、私達の必ず表示しなければならないのはpublicキーワードを表示します.しかし、Type Scriptではpublicはデフォルトのアクセスレベルであり、cxiのようなprvateではなくデフォルトである.
隠しタイプの内部メンバーコントロールクラスのメンバーの視認性を期待していますが、この時は「prvate」というキーワードを使ってメンバーを表示することができます.もし私達が“Animal”のname属性を隠したいなら:
class Animal {
    private name:string;
    constructor(theName: string) { this.name = theName; }
    move(meters: number) {
        alert(this.name + " moved " + meters + "m.");
    }
}
  private(  )
Type Scriptは構造化されたタイプ(またはアヒルのタイプ)のシステムがあります.私たちは2つのタイプを比較していますが、私たちはどちらから来たのかに関心がなく、タイプごとの互換性に関心を持っています.すべてのメンバーが互換性があれば、この2つのタイプも互換性があると思います.
タイプチェックシステムが2つの「prvate」のメンバーを比較すると、異なる対象となります.2つのタイプの比較については、1つのタイプがプライベートメンバを持つ場合、他のクラスは同じ宣言のプライベート変数を含む必要があります.以下の例:
class Animal {
    private name:stringParameter properties;
    constructor(theName: string) { this.name = theName; }
}

class Rhino extends Animal {
    constructor() { super("Rhino"); }
}

class Employee {
    private name:string;
    constructor(theName: string) { this.name = theName; }   
}

var animal = new Animal("Goat");
var rhino = new Rhino();
var employee = new Employee("Bob");

animal = rhino;
animal = employee; //error: Animal and Employee are not compatible
  
上記の例では、「Animal」と「Rhino」の2つのタイプがありますが、「Rhino」は「Animal」のサブタイプです.また、「Employee」のクラスも定義しています.「Animal」と全く同じです.私たちはそれぞれ第3のクラスのオブジェクトを作成し、相互に値を割り当て、結果’Animal’と’Rhino’との関係を引き継いでいますので、プライベートフィールドnameについては“Animal”で同じ声明を持っています.“prvate name:string”は互換性があります.しかし、「Employee」については、それぞれプライベートなnameフィールドを宣言しています.プライベートフィールドについては異なりますので、employeeをanimalオブジェクトに割り当てることはできません.彼らは互換性のないタイプです.
パラメータのプロパティ(Parameter properties)
アクセス制限キーワードpublic’と’prvateは、パラメータ属性によって、クラスメンバーフィールドを素早く初期化することもできます.パラメータ属性は、私たちにステップでクラスメンバーを作成させます.次の例は上の例では「theName」を削除し、「prvate name:string」声明を用いてコンストラクションパラメータにおいて、私たちのためにプライベートなnameメンバーを作成しながらこのフィールドを初期化します.
class Animal {
    constructor(private name: string) { }
    move(meters: number) {
        alert(this.name + " moved " + meters + "m.");
    }
}
  
ここでは「prvate」というキーワードを利用して、プライベートメンバーを作成し、その値を初期化します.publicにも似ています.
アクセス器(Access ors)
Type Scriptはgetters/settersを利用してメンバーへのアクセスを制御することをサポートしています.クラスのメンバー間のアクセス方法を制御できます.
以下のプレゼンテーションでは、どのように普通のクラスをget/set方式に変換するかを示します.以下のように、get/setがない方法です.
class Employee {
    fullName: string;
}

var employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
    alert(employee.fullName);
}
  
ここでは任意のアクセスを許可します.これは私たちが望むものではないかもしれません.
下でfullNameを修正する時、正しいpasscodeを提供しなければなりません.このようなnameを任意に修正できないようにします.
var passcode = "secret passcode";

class Employee {
    private _fullName: string;

    get fullName(): string {
        return this._fullName;
    }

    set fullName(newName: string) {
        if (passcode && passcode == "secret passcode") {
            this._fullName = newName;
        }
        else {
            alert("Error: Unauthorized update of employee!");
        }
    }
}

var employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
    alert(employee.fullName);
}
  
ここでfullName属性を修正する時に、passcodeの値を検証しました.修正する権限がありますか?passcodeの値を変えてみてもいいです.不一致にして、どんな問題が起こるかを観察してみてください.
注意:アクセスはECMAScript 5としてコンパイル出力を設定する必要があります.
静的な属性
クラスのテーマに戻ります.上に述べたように、カテゴリを作成する方法についての例示的なメンバーです.クラスレベルのアクセスとして認識されるクラスの静的なメンバも作成できます.私たちは‘static’のキーワードを使ってクラスのメンバーを表示することができます.下記の例では表の原点はすべての表に共通していますので、クラスのメンバーを「static」で定義することができます.このメンバーにはクラス名を用いて訪問することができ、対象メンバーのような「this.」
class Grid {
    static origin = {x: 0, y: 0};
    calculateDistanceFromOrigin(point: {x: number; y: number;}) {
        var xDist = (point.x - Grid.origin.x);
        var yDist = (point.y - Grid.origin.y);
        return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
    }
    constructor (public scale: number) { }
}

var grid1 = new Grid(1.0);  // 1x scale
var grid2 = new Grid(5.0);  // 5x scale

alert(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
alert(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
  
高度な特性
構造関数
私たちはType Scriptの中で一つのカテゴリーを宣言すると、いくつかの種類の声明を作成することがあります.最初のクラスの例:
class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

var greeter: Greeter;
greeter = new Greeter("world");
alert(greeter.greet());
  
ここで「var greeter:Greter」は、まずGreerクラスのインスタンス変数を宣言します.これは多くのOO言語の中で自然な方式です.
このクラスの例はnewキーワードを用いても実装され、オブジェクトを初期化するためにコンストラクタを呼び出します.以下は同じJavaScriptがどうやって行うかを見てみます.
var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

var greeter;
greeter = new Greeter("world");
alert(greeter.greet());
ここで'var Greer'はコンストラクタに割り当てられ、new'を用いてこの方法を呼び出してクラスの実例を得る.同様に私たちのクラスも静的変数を含んでいます.すべてのクラスがインスタンスとスタティックの2つのタイプのメンバーを持つことができると考えられています.
上の例に対して少し修正しましょう.
class Greeter {
    static standardGreeting = "Hello, there";
    greeting: string;
    greet() {
        if (this.greeting) {
            return "Hello, " + this.greeting;
        }
        else {
            return Greeter.standardGreeting;
        }
    }
}

var greeter1: Greeter;
greeter1 = new Greeter();
alert(greeter1.greet());

var greeterMaker: typeof Greeter = Greeter;
greeterMaker.standardGreeting = "Hey there!";
var greeter2:Greeter = new greeterMaker();
alert(greeter2.greet());
  
ここでは「greeter 1」は前の仕事とよく似ています.私たちは「グリーン」クラスを初期化して、このオブジェクトを呼び出します.その結果は上の例で見られました.
続いて、私たちは直接にクラス訪問を使いました.まず、私達は新しい「greeterMaker」の変数を定義しました.この変数はグリーンタイプの情報を保持しています.ここでは「typeof Greter」を使って、Greer自身の種類情報を返します.このタイプの情報には、したがって、静的メンバ情報と、具体的なオブジェクトの構造関数情報が含まれます.その後、「new」greeterMakerによってGreerの例示的なオブジェクトを作成し、その方法greetを呼び出している.
インターフェースを利用してクラスを使います.
上記のように、クラスは主にクラスのインスタンスタイプと構造関数の2つのことを声明しています.クラスは主にタイプを作るので、同じところでインターフェースを使って代替できます.
class Point {

x: number;
y: number;
}

interface Point3d extends Point {

z: number;
}

var point3d: Point3d = {x: 1, y: 2, z: 3};
  
注意:Type Scriptはタイプ検査のためのタイプ推定です.