类
typescript
里的类和javascript
里的类基本一样。typerscript
扩展了类,它可以通过先声明的方式限制实例属性的类型,并且还引入了类似C++
、Java
的继承权限设定,拥有public
、protect
、private
三种修饰符。若不声明权限则默认为public
修饰符 | 外部访问 | 派生类访问 | 自身访问 |
---|---|---|---|
public | √ | √ | √ |
protected | × | √ | √ |
private | × | × | √ |
public
public
修饰的属性可以在外部访问,也可以在派生类和自身实例中访问
class Person {
name: string
age: number
constructor(name:string, age:number) {
this.name = name
this.age = age
}
say(): void {
console.log(`My name is ${this.name},I'm ${this.age} years old`)
}
}
class Student extends Person {
course: string
constructor(name:string, age:number, course:string) {
super(name, age)
this.course = course
}
say() {
super.say()
console.log(`My course is ${this.course}`)
}
}
let man1: Person = new Person('sphinx', 16)
console.log(man1.name) // sphinx
man1.say() // My name is sphinx,I'm 16 years old
let man2: Student = new Student('asuhe', 16, 'math')
man2.say() // My name is asuhe,I'm 16 years old
// My course is math
protected
protected
修饰的属性不可以在外部访问,但可以在派生类和自身实例中访问
class Person {
protected name: string
protected age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
say(): void {
console.log(`My name is ${this.name},I'm ${this.age} years old`)
}
}
class Student extends Person {
course: string
constructor(name: string, age: number, course: string) {
super(name, age)
this.course = course
}
say() {
super.say()
console.log(`My course is ${this.course}`)
}
}
let man1: Person = new Person('sphinx', 16)
console.log(man1.name) // error
man1.say() // My name is sphinx,I'm 16 years old
let man2: Student = new Student('asuhe', 16, 'math')
man2.say() // My name is asuhe,I'm 16 years old
// My course is math
private
protected
修饰的属性仅能自身实例中访问
class Person {
private name: string
private age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
say(): void {
console.log(`My name is ${this.name},I'm ${this.age} years old`)
}
}
let man1: Person = new Person('sphinx', 16)
console.log(man1.name) // error
console.log(man1.age) // error
man1.say() // My name is sphinx,I'm 16 years old
readonly vs 权限修饰符
当我们希望一个属性仅可自身访问且仅可读取时,可以和readonly
修饰符一起使用
class Goods {
public readonly id:number
constructor(id:number){
this.id = id
}
}
存取器
TypeScript
支持通过 getters/setters
来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。
下面来看如何把一个简单的类改写成使用 get
和 set
。 首先,我们从一个没有使用存取器的例子开始。
class Person {
firstName: string = 'A'
lastName: string = 'B'
get fullName () {
return this.firstName + '-' + this.lastName
}
set fullName (value) {
const names = value.split('-')
this.firstName = names[0]
this.lastName = names[1]
}
}
const p = new Person()
console.log(p.fullName)
p.firstName = 'C'
p.lastName = 'D'
console.log(p.fullName)
p.fullName = 'E-F'
console.log(p.firstName, p.lastName)
抽象类
抽象类做为其它派生类的基类使用。 **它们不能被实例化。**不同于接口,抽象类可以包含成员的实现细节。 abstract
关键字是用于定义抽象类和在抽象类内部定义抽象方法。
/*
抽象类
不能创建实例对象, 只有实现类才能创建实例
可以包含未实现的抽象方法
*/
abstract class Animal {
abstract cry ()
run () {
console.log('run()')
}
}
class Dog extends Animal {
cry () {
console.log('Dog cry()')
}
}
const dog = new Dog()
dog.cry() // Dog cry()
dog.run() // run()
抽象类 vs 接口
接口可以理解为里面所有属性都是abstract
,而且使用了接口的类必须按接口的规格实现。接口的函数只能是定义,不能有函数体不能实现。
抽象类里的函数方法可以为abstract
也可以不为abstract
,而且抽象类的函数方法可以有函数体能够去实现。若抽象类的函数方法被实现类重写了,那么在实现类调用该方法时会调用实现类重写的那个方法。