1

TypeScript-Class

typescript之旅

1.TypeScript-Basic
2.TypeScript interface
3.Typescript-module(1)
4.TypeScript Modules(2)
5.Typescript tsconfig
6.TypeScript Functions
7.Typescript Class

Class

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

let greeter = new Greeter("world");
  • 对于这个demo的理解怎么说呢?

  • 如果你是java或C#程序员,你应该这样理解:

public class Greeter{
    public String greeting;
    public Greeter(String message){
        this.greeting = message;
    }
    public string greet(){
        return "Hello, " + this.greeting;
    }
}
  • 如果你是javascript程序员,那你应该这样理解

function Greeter(message){
    this.greeting = message;
}
Greeter.prototype.greet = function(){
    return "Hello, " + this.greeting;
}

参数属性

  • 对于上个例子,有一种简写方法

class Animal {
    constructor(private name: string) { }
    move(distanceInMeters: number) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}
  • 仅在构造函数里使用private name: string参数来创建和初始化name成员。 我们把声明和赋值合并至一处。

  • 参数属性通过给构造函数参数添加一个访问限定符来声明。 使用private限定一个参数属性会声明并初始化一个私有成员;对于public和protected来说也是一样。

继承

class Animal {
    name:string;
    constructor(theName: string) { this.name = theName; }
    move(distanceInMeters: number = 0) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 5) {
        console.log("Slithering...");
        super.move(distanceInMeters);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 45) {
        console.log("Galloping...");
        super.move(distanceInMeters);
    }
}

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

sam.move();
tom.move(34);
  • 这个代码的理解呢?java程序员应该很好理解吧,子类重写了父类方法move,然后父类引用指向子类对象,多态实现了!

  • 重点是javascript如何理解呢?

本质是javascript的原型继承,如果你想了解javascript继承高仿

OOP,我这里有一篇文章javascript继承

公共,私有与受保护的修饰符

  • 想必是java同学前面一直有的疑问吧?

首先记住默认共有
第一个例子我可是全部加了public关键字的哦

理解private

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

new Animal("Cat").name; // Error: 'name' is private;

理解protected

  • protected修饰符与private修饰符的行为很相似,但有一点不同,protected成员在派生类中仍然可以访问。例如:

class Person {
    protected name: string;
    constructor(name: string) { this.name = name; }
}

class Employee extends Person {
    private department: string;

    constructor(name: string, department: string) {
        super(name)
        this.department = department;
    }

    public getElevatorPitch() {
        return `Hello, my name is ${this.name} and I work in ${this.department}.`;
    }
}

let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());
console.log(howard.name); // error
  • 构造函数也可被标记为protected. 这就是说这个类不能在包含它的类之外实例外,但是可以被继承。比如,

class Person {
    protected name: string;
    protected constructor(theName: string) { this.name = theName; }
}

// Employee can extend Person
class Employee extends Person {
    private department: string;

    constructor(name: string, department: string) {
        super(name);
        this.department = department;
    }

    public getElevatorPitch() {
        return `Hello, my name is ${this.name} and I work in ${this.department}.`;
    }
}

let howard = new Employee("Howard", "Sales");
let john = new Person("John"); // Error: The 'Person' constructor is protected
  • 想什么,对抽象类

Get/Set

class Employee {
    private _fullName: string;

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

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

let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
    alert(employee.fullName);
}
  • 和C#很像

静态属性

  • 使用很简单的,属性前加static关键字

class Grid {
    static origin = {x: 0, y: 0};
    calculateDistanceFromOrigin(point: {x: number; y: number;}) {
        let xDist = (point.x - Grid.origin.x);
        let yDist = (point.y - Grid.origin.y);
        return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
    }
    constructor (public scale: number) { }
}

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

console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

console.log(Grid.origin);

抽象类

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
}

高级技巧

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());
  • greeter的类型是Greeter, Greeter的类型是typeof Greeter

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());
  • 这个语法不常用,据我所知只在动态加载中有用

  • 抽象方法的语法与接口方法相似:定义方法签名不包含方法体

  • 区别:抽象类:抽象方法必须使用abstract关键字并且可以包含访问符


Sike
272 声望18 粉丝