虽然 JavaScript 中有类的概念,但是可能大多数 JavaScript 程序员并不是非常熟悉类,这里对类相关的概念做一个简单的介绍。
类的概念
TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public、private 和 protected。
不允许多继承,只能单继承
class Person {
private name: string;
private sex: boolean;
private age: number = 0;
// 只允许被子类继承,无法实例化
protected constructor(name: string, age: number, sex: boolean) {
this.name = name;
this.age = age;
this.sex = sex;
}
toString() {
console.log(`my name is ${
this.name}, ${
this.age} years old. I am a ${
this.sex ? 'men':'women'}.`);
}
}
// 继承
class Men extends Person {
constructor(name: string, age: number) {
super(name, age, true);
}
}
// protected不允许被实例化
// let p = new Person("laowan", 20, true);
let men = new Men("laowan", 20);
men.toString();
class Person {
private name: string;
private sex: boolean;
private age: number = 0;
// 只允许被子类继承,无法实例化
constructor(name: string, age: number, sex: boolean) {
this.name = name;
this.age = age;
this.sex = sex;
}
toString() {
console.log(`my name is ${
this.name}, ${
this.age} years old. I am a ${
this.sex ? 'men':'women'}.`);
}
}
// 继承
class Men extends Person {
constructor(name: string, age: number) {
super(name, age, true);
}
}
class Women extends Person {
constructor(name: string, age: number) {
super(name, age, false);
}
}
// 多态
let p: Person = new Person("laowan", 23, true);
p.toString();
p = new Men("xiaowan", 23);
p.toString();
p = new Women("xiaoli", 18);
p.toString();
class Person {
get name(): string {
return this._name;
}
set name(value: string) {
this._name = value;
}
private _name: string;
constructor(name: string) {
this._name = name;
}
}
class Person {
static type: string = "person"
static getType() {
return this.type
}
}
console.log(Person.type);
console.log(Person.getType());
class Person {
readonly name:string;
}
let p = new Person();
// Error:(6, 3) TS2540: Cannot assign to 'name' because it is a read-only property.
p.name = "123";
readonly只能用在类的属性
abstract class Person {
protected name: string;
constructor(name: string) {
this.name = name;
}
// 子类必须实现该方法
abstract toString(): string;
}
class Men extends Person {
toString(): string {
return `I am a men, my name is ${
this.name}`;
}
}
class Women extends Person {
toString(): string {
return `I am a women, my name is ${
this.name}`;
}
}
ts支持实现多接口
// 动物
class Animal {
protected type: string;
public eat(): void {
console.log(`${
this.type}在吃东西.`);
}
}
// 游
interface Swim {
swim(): void;
}
// 飞
interface Fly {
fly(): void;
}
// 鱼是会游泳的动物
class Fish extends Animal implements Swim {
swim(): void {
console.log("鱼在水中游泳,通过鱼鳍控制方向");
}
}
// 鸭子是会游泳且会飞的动物
class Duck extends Animal implements Swim, Fly{
fly(): void {
console.log("鸭子可以飞,但是飞的不高");
}
swim(): void {
console.log("鸭子在水面上游泳,通过鸭掌控制方向");
}
}
let fish = new Fish();
fish.eat();
fish.swim();
let duck = new Duck();
duck.eat();
duck.swim();
duck.fly();
interface Alarm {
alert();
}
// 接口继承接口
interface LightableAlarm extends Alarm {
lightOn();
lightOff();
}
class Point {
x: number;
y: number;
}
// 接口继承类
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {
x: 1, y: 2, z: 3};
interface Point {
x: number;
y: number;
}
let p: Point = {
x: 1, y: 1};
class Point3d implements Point {
// 必须要有 x、y
x: number;
y: number;
z: number;
}
let p3d: Point3d = {
x: 0, y: 0, z: 0};
interface SumFunc {
(numList:number[]): number;
}
let sum: SumFunc = function (numList: number[]) {
return numList.reduce((p, c) => p + c, 0)
};
let sumFloor: SumFunc = function (numList: number[]) {
return Math.floor(numList.reduce((p, c) => p + c, 0))
};
let arr = [1,2,3,4,5,6.6];
console.log(sum(arr));
console.log(sumFloor(arr));
使用问号标识一个属性,表示这个属性是可选的
// 可选属性
interface Interface {
name: string;
age?: number;
}
class Class1 implements Interface {
age: number;
name: string;
}
class Class2 implements Interface {
name: string;
}
// 同样可用于函数上
function f2(name: string, age?: number) {
console.log(name);
if (age) {
console.log(age);
}
}