class Human {
name: string
constructor(name: string ){
this.name = name
}
greet():void {
console.log(`hello, my name is ${this.name}`)
}
}
let per1 = new Human('yuusha')
per1.greet()
class Animal {
name: string
constructor(name: string){
this.name = name
}
move(speed: number = 0): void {
console.log(`${this.name} moves at speed: ${speed}`)
}
}
class Horse extends Animal {
legs: number
constructor(name: string, legs: number){
super(name)
this.legs = legs
}
move(speed: number = 5): void {
console.log('this horse is running...')
super.move(speed)
}
}
class Snake extends Animal {
length: number
constructor(name: string, length: number){
super(name)
this.length = length
}
move(speed: number = 3): void {
console.log('this snake is running ...')
super.move(speed)
}
}
let horse: Horse = new Horse('HorseName', 4)
let snake: Animal = new Snake('SnakeName', 1)
horse.move()
snake.move()
super()
;TypeScript中成员默认修饰符为 public
,也可以显式地声明为public
。
class Animal {
public name: string
public constructor(name: string) {
this.name = name
}
public move(speed: number){
console.log(`${this.name} moves at speed ${speed}`)
}
}
当成员被标记为 private
, 则不能在声明它的类的外部访问。
class Animal {
private name: string
constructor(name: string) {
this.name = name
}
}
new Animal('a').name // Error
protected
与private
类似,但是可以在子类中访问。
class Animal {
protected name: string
constructor(name: string) {
this.name = name
}
}
class Dog extends Animal {
constructor(name: string){
super(name)
}
showName(): void {
console.log(this.name)
}
}
new Dog('doggy').showName()
构造函数也可以定义为 protected
或 private
类型,此时无法在类外部使用构造函数创建该类的实例。
典型应用是 Singleton
模式:
class EagerSingleton {
private static instance: EagerSingleton = new EagerSingleton()
public data: any
private constructor() { }
public static getInstance(){
return EagerSingleton.instance
}
}
const instance1 = EagerSingleton.getInstance()
const instance2 = EagerSingleton.getInstance()
instance1.data = 123
console.log(instance1.data) // 123
instance2.data = 456
console.log(instance1.data) // 456
可以使用 readonly
关键字将属性设置为只读的(类似于其他语言中的 final
关键字)。
只读属性只能在声明时或者构造函数里初始化。
class Circle {
readonly PI: number
radius: number
constructor(pi: number, radius: number){
this.PI = pi
this.radius = radius
}
getSquare():number {
return this.PI * this.radius * this.radius
}
}
const circle = new Circle(3.14, 20)
console.log(circle.getSquare())
circle.radius = 25
console.log(circle.getSquare())
// circle.PI = 3.1415926 // Error, readonly
参数属性通过给构造函数的参数添加一个访问限定符(public、 private、 protected)来声明,可以将属性的创建和初始化在构造函数中完成。
class Animal {
constructor(private name: string) { }
}
typescript
支持使用 getters/setters
来控制对于对象成员的访问。
class Demo {
private _name: string
set name(name: string){
this._name = name
}
get name(): string {
return this._name
}
}
只有
get
而没有set
的属性自动被推断为readonly
属性。
抽象类作为基类供其他派生类继承, 一般不会直接实例化。使用 abstract
关键字定义抽象类和在抽象类中定义抽象方法。
private
),而接口的方法签名都是 public
。// 抽象类
abstract class Animal{
constructor(protected _name: string){}
abstract speak(): void
move(): void {
console.log(this._name + 'is moving')
}
}
class Dog extends Animal {
speak(): void {
console.log(this._name + ' is barking')
}
eat(): void {
console.log(`${this._name} is eating`)
}
}
// let jim: Dog = new Dog('Jim')
let jim: Animal = new Dog('Jim') // 可以定义为基类类型
jim.speak()
jim.move()
// jim.eat() // Error, 定义为Animal类型,所以没有eat()方法