好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

typescript中的类

typescript 中的类与 es6 中的类在使用上基本一样,举个小例子:

 class Person{
  name:string;
  constructor(name:string){
      this .name =  name
  }
  sayHi(){
    console.log( 'hi' )
  }
}

  //   定义 Teacher 继承 Person 
 class Teacher extends Person{
  constructor(name:string){
    super(name)
  }
  teach(){
    console.log( 'teach' )
  }
}

const teacher  =  new  Teacher('Tom' )
console.log(teacher.name)   //   Tom 
teacher.sayHi()  //   hi 
teacher.teach()  //   teach 

 

例子中实现了类的基本定义以及类的继承。如果了解 es6 的话,理解起来不难,需要注意的是 typescript 中强制你在派生类的构造函数中必须调用 super(),即在构造函数里访问  this  的属性之前,我们一定要调用  super(),它执行基类的构造函数。

基类是指父类,也被叫做“超类”,派生类则是子类。

 

修饰符

typescript 中为类提供了四个修饰符,分别是 public(公共的)、private(私有的)和 protected(受保护的),还有一个 readonly(只读)。

 

public

默认情况下 typescript 中定义的属性和方法都是公共的,即可以在类的外部访问到。有时 TSLint 可能会要求你必须用修饰符来表明这个属性或方法是什么类型的,手动添加即可,如下:

 class Point{
  public x:number;
  public y:number;

  constructor(x:number,y:number){
      this .x =  x
      this .y =  y
  }

  public getPosition(){
      return  `${ this .x}:${ this  .y}`
  }
} 

 

private

当成员被标记成  private 时,它就不能在声明它的类的外部访问。比如:

 class Animal{
  private name:string;

  constructor(name:string){
      this .name =  name
  }

  getName(){
    console.log(  this  .name)
  }
}

const cat  =  new  Animal('cat' )

console.log(cat.name)   //   Property 'name' is private and only accessible within class 'Animal'. 
 
cat.getName()   //   cat 

 

protected 

protected 与 private 类似,区别在于被 protected 标记的属性可以在子类中访问到,而 private 标记的属性不能在子类中访问到。

 class Person{
  protected name:string;

  constructor(name:string){
      this .name =  name
  }
}

class Student extends Person{
  private age:number;

  constructor(name:string,age:number){
    super(name)
      this .age =  age
  }

  getName(){
    console.log(  this  .name)
  }
}

const s  =  new  Student('小明',18 )

s.getName()   //   小明 
 
console.log(s.name)   //   属性 “name” 受保护,只能在类 “Person”及其子类中访问 

 

上述例子中,name 属性可以在子类 Student 中获取,但是在类的外部就获取不到了。

 

protected 还可以标记构造函数,意味着这个被标记的类不能被实例化,只能继承:

 class Person{
  protected constructor(){
    
  }
}

const p  =  new  Person()  //   类 “Person” 的构造函数是受保护的,仅可在类声明中访问 
 
class Student extends Person{
  constructor(){
    super()
  }
}

const s  =  new  Student()

 

readonly

使用  readonly  关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。

 class UserInfo{
  readonly name:string;

  constructor(name:string){
      this .name =  name
  }
}

const user  =  new  UserInfo('Tom' )

user.name  = 'Bob'  //   Cannot assign to 'name' because it is a read-only property 

 

参数属性

参数属性可以用来简化一个过程。什么过程?就拿上面的例子来说,我们在 UserInfo 类里,定义一个只读属性 readonly 和一个参数为 name 的构造函数,然后要在构造函数中进行 this.name = name 的赋值,这种操作是经常遇到的,利用参数属性我们可以简化这个过程,变成如下这样:

 class UserInfo{
  constructor(readonly name:string){}
}

const user  =  new  UserInfo('Tom' )
console.log(user.name)   //   Tom 

现在仅在构造函数里使用  readonly name: string  参数来创建和初始化  name 成员,把声明和赋值合并至一处了。

 

参数属性简单来说就是在 constructor 构造函数的参数前面加上访问限定符,也就是前面说的 public、private、protected 和 readonly 中的任意一个。

 

静态属性 

在 TS 中使用 static 关键字来指定属性或方法是静态的,实例不会添加这个静态属性,也不会继承静态方法。

 class Car{
  static color:string  = 'red' ;
  getColor(){
    console.log(Car.color)
  }
  constructor(){
      //  
   }
}

const p  =  new   Car()
console.log(p.color)   //   Property 'color' is a static member of type 'Car' 
p.getColor()  //   red 

 

可选属性

使用 ? 符号来标记可选属性:

 class Info{
  name:string;
  age ? :number;

  constructor(name:string,age ?:number,sex? :string){
      this .name =  name
      this .age =  age
  }
}

const info1  =  new  Info('A' )
const info2  =  new  Info('B',18 )
const info3  =  new  Info('C',18,'man')

 

存取器

存取器即是存值函数和取值函数,也就是在设置属性值的时候调用的函数,和在访问属性值的时候调用的函数,使用关键词 get 和 set。

 class Info{
  private _name:string;

  get name(){
      //   在获取值前,可以做一些判断操作 
     return   this  ._name
  }

  set name(value){
      //   在设置值前,可以做一些判断操作 
     this ._name =  value
  }

  constructor(){
      //
    }
}

const info  =  new   Info()
info.name  = 'Tom' 
console.log(info.name)   //   Tom 

 

抽象类

抽象类用来被其他类继承,而不能被实例化,使用  abstract  关键字定义抽象类和在抽象类内部定义抽象方法。

 abstract class People{
  name:string
  constructor(name:string){  this .name =  name}
  abstract printName():  void  
}

class Man extends People{
  constructor(name:string){
    super(name)
  }
    //   抽象方法无法从父类继承,需要自己实现 
   printName(){
    console.log(  this  .name)
  }
}

const m  =  new  Man('Tom' )
m.printName()   //   Tom 
 
const p  =  new  People()  //   无法创建抽象类的实例 

 

abstract 关键字也可以定义抽象属性和抽象存取器:

 abstract class People{
  abstract name:string
  abstract printName():  void  
  abstract get insideName():string
  abstract set insideName(value:string)
  
  constructor(name:string){}
} 

 

 

 

 

查看更多关于typescript中的类的详细内容...

  阅读:36次