自我提升TS知识体系
类
传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的。 从ECMAScript 2015,也就是ECMAScript 6开始,JavaScript程序员将能够使用基于类的面向对象的方式。 使用TypeScript,我们允许开发者现在就使用这些特性,并且编译后的JavaScript可以在所有主流浏览器和平台上运行,而不需要等到下个JavaScript版本。
类
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
console.log("result===>",greeter.greet()); //result===> Hello, world
上面代码其实已经我们接触到的面向对象语言是一样的,命名方式和Java或者c#都是一样,我们在类中定义了三个基本成员,分别是属性、构造方法、方法。我们在类中引用类成员时都要用到this,它表示我们访问的是类的成员。最后一行,我们使用 new构造了 Greeter类的一个实例。 它会调用之前定义的构造函数,创建一个 Greeter类型的新对象,并执行构造函数初始化它。注意:构造函数只有new 关键字创建类或对象时才会被调用并初始化执行。
继承
在TypeScript里,我们可以使用常用的面向对象模式。 基于类的程序设计中一种最基本的模式是允许使用继承来扩展现有的类。
看下面的例子:
class Animal {
move(distanceInMeters: number = 0) {
console.log(`Animal moved ${distanceInMeters}m.`);
}
}
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
}
const dog = new Dog();
dog.move(); //Animal moved 0m.
dog.bark(); //Woof! Woof!
dog.move(10); //Animal moved 10m.
dog.bark(); //Woof! Woof!
这个例子展示了最基本的继承:类从基类中继承了属性和方法。 这里, Dog是一个 派生类,它派生自 Animal 基类,通过 extends关键字。 派生类通常被称作 子类,基类通常被称作 超类。
因为 Dog继承了 Animal的功能,因此我们可以创建一个 Dog的实例,它能够 bark()和 move()。
下面我们来看个更加复杂的例子。
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(); // Slithering...
// Sammy the Python moved 5m.
tom.move(34); // Galloping...
// Tommy the Palomino moved 34m.
这个例子展示了一些上面没有提到的特性。 这一次,我们使用 extends
关键字创建了 Animal
的两个子类: Horse
和 Snake
。
与前一个例子的不同点是,派生类包含了一个构造函数,它 必须调用 super()
,它会执行基类的构造函数。 而且,在构造函数里访问 this的属性之前
,我们 一定要调用 super()
。 这个是TypeScript强制执行
的一条重要规则
。
这个例子演示了如何在子类里可以重写父类
的方法
。 Snake
类和 Horse
类都创建了 move
方法,它们重写了从 Animal
继承来的 move
方法,使得 move
方法根据不同的类而具有不同的功能。 注意,即使 tom
被声明为 Animal
类型,但因为它的值是 Horse
,调用 tom.move(34)
时,它会调用 Horse
里重写的方法:
公共,私有与受保护的修饰符
默认为 public
在上面的例子里,我们可以自由的访问程序里定义的成员。 如果你对其它语言中的类比较了解,就会注意到我们在之前的代码里并没有使用 public
来做修饰;例如,C#
要求必须明确地使用 public
指定成员是可见的。 在TypeScript
里,成员都默认为 public
。
你也可以明确的将一个成员标记成 public
。 我们可以用下面的方式来重写上面的 Animal
类: