TypeScript-类

在js中,类(Class)定义了一件事物的抽象特点,包含它的属性和方法。对象(Object)为类的实例,可以通过new关键字生成。
面向对象的三大特性:封装,继承,多态
封装:将对数据的操作细节隐藏起来,只暴露对外的接口。通过对外提供的接口来访问该对象,同时也保证外界无法任意更改对象内部的数据。
继承:子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
多态:由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。
存取器(getter&setter):用以改变属性的读取和赋值行为。
修饰符:一些用于限定成员或类型的性质的关键字。例如public

  • TypeScript中类的用法:
class Person{
    name: string
    age:number
    gender:string
    constructor(name:string='Liane',age:number=18,gender:string='female'){
    this.name = name
    this.age = age
    this.gender = gender
    }
    sayHi(str:string){
        console.log(`Hi ${str}, My name is ${this.name}, I'm ${this.age} years old`)
    }
}
let p0 = new Person()
p0.sayHi('Ann')
  • 继承:

    使用extends关键字,让子类继承自父类,使用super关键字调用父类的构造函数和实例方法,继承父类的属性和方法

class Students extends Person{
    constructor(name: string, age:number,gender:string){
        super(name,age,gender)
    }
    sayHi(str){
        super.sayHi(str)
    }
}
let s0 = new Students('Jack',16,'man');
s0.sayHi('Liane')
  • 多态:

由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。

class Animal{
    name: string
    constructor(name: string){
        this.name = name
    }
    eat(str:string){
        console.log(`${this.name} like to eat ${str}`)
    }
}
class Dog extends Animal{
    constructor(name:string='Tom'){
        super(name)
    }
    eat(str){
        super.eat(str)
    }
}
class Cat extends Animal{
    constructor(name:string='Jerry'){
        super(name)
    }
    eat(str:string){
        super.eat(str)
    }
}

let dog = new Dog()
let cat = new Cat()
dog.eat('bone') //Tom like to eat bone
cat.eat('fish') //Jerry like to eat fish

即Dog和Cat都继承自Animal,但分别实现了自己的eat方法。

  • 类中的成员修饰符
    用来描述类中的属性、构造函数和方法的可访问性

public:默认修饰符,代表是公共的,在任何位置都可以被访问。

private:私有修饰符,外部和子类都无法访问这个成员。
当希望有的成员无法直接存取时,可使用private修饰符修饰该成员。
使用private修饰constructor时,该类不允许被继承或者实例化。

protected:该修饰符修饰的成员,只能在其内部及子类中被访问
使用protected修饰constructor时,该类只允许被继承,不允许实例化。

注:仅在TS编译时提示错误,在编译成js后,并没有限制private属性在外部的可访问性或protected修饰构造函数的可实例化性。

  • readonly修饰符
    修饰类中的属性成员,被修饰的属性不能在外部或类中的普通方法中被随意修改。可以在构造函数constructor中被修改。
//readonly修饰类中的属性
class Person{
    readonly name:string='jack' //可设置默认值
    constructor(name:string){
        this.name = name //可以在构造函数中修改name  
    }
    sayHi(){
        this.name = 'Hello' //提示错误
    }
}
let p = new Person('Liane')//允许实例化传入新的name值
p.name = 'Ann' //提示错误
console.log(p.name) //Ann--即使提示错误,但若继续编译,编译后的js依然不会限制修改readonly修饰的属性

使用readonly修饰constructor的参数时,被修饰的参数称为参数属性

class Person{
    constructor(readonly name:string){
        this.name = name
    }
}
let p1 = new Person('Liane')
consoel.log(p1.name) //Liane
p1.name = 'Jack' //提示错误
//我们发现,在cosntructor的参数前加上修饰符readonly,则该类中会自动添加一个被readonly修饰的属性成员,类比不难发现,构造函数参数使用public,private,protected与使用readonly一致。

构造函数中的参数可以使用readonly进行修饰,一旦修饰,则该类中就有了这个只读参数的成员属性,外部可以访问,但不能修改。
同理,构造函数中的参数可以使用public,private和protected进行修饰,无论是哪个修饰符,该类中都会自动添加一个被该修饰符修饰的属性成员。

  • 存取器
    让我们可以有效的控制对对象中的成员的访问和修改。通过getter和setter来进行操作。
class Person{
    firstName: string
    lastName: string
    constructor(firstName:string,lastName:string){
        this.firstName = firstName
        this.lastName = lastName
    }
    get fullName(){
        return this.firstName + '_' +this.lastName
    }
    set fullName(value){
        const names = value.split('_')
        this.firstName = names[0]
        this.lastName = names[1]
    }
}
let p = new Person('诸葛','孔明')
console.log(p.fullName) //诸葛_孔明
p.fullName = '司马_相如'
console.log(p.firstName) //司马
  • 静态成员
    在类中通过static修饰的属性或方法,称为静态属性和静态方法,也称为静态成员。静态成员不会被实例继承,但可以被子类继承。
    静态成员使用时通过类名.xxx的语法来调用
class A{
    static n:number = 0
    static fun(){
        A.n++
        console.log(A.n)
    }
}
let a0 = new A()
console.log(a0.n) //提示错误,继续编译后会打印undefined
console.log(a0.fun()) //提示错误,编译后会报错
console.log(A.n) //0
A.n = 100
console.log(A.n) //100
A.fun() //101
  • 抽象类
    抽象类:包含抽象方法(抽象方法一般没有任何具体内容的实现),也可以包含实例方法,抽象类是不能被实例化的,为了让子类进行实例化及实现内部的抽象方法。
    使用abstract定义一个抽象类和其中的抽象方法。
//定义一个抽象类
abstract class Animal1{
    name:string
    age: number
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }
    abstract eat(str) //定义一个抽象方法,抽象方法不允许具有任何内容
    sayHi(){ //抽象类可以包含实例方法
        console.log(`Hi,I am ${this.name}`)
    }
}
//定义一个子类继承自抽象类
class Dog1 extends Animal1{
    eat(str){ //必须定义抽象方法的实例方法,否则报错
       console.log(`${this.name} like to eat ${str}`) 
    }
}
let dog0 = new Animal1('Jack') //报错
let dog1 = new Dog1('Jack',2)
dog1.eat('bone') //Jack like to eat bone
dog1.sayHi() //Hi,I am Jack

你可能感兴趣的:(TypeScript-类)