四.类——Class
ts里面的类与js的类大同小异,无非是做了一些了类型校验和功能拓展。
基本使用
我们使用class
关键字来声明一个类,并进行一些实例属性与方法的声明。
class Dog {
//定义几个实例属性
name: string = '小狗'
age: number = 5
//定义一个实例方法,该方法会绑定在类的原型对象上
sayHi() {
console.log('Hi')
}
}
let dog = new Dog() //Dog: {"name": "小狗","age": 5}
dog.sayHi() //hi
手动设置属性值
上面代码里我们的实例属性是写死的,实用性并不高,我们使用constructor
尝试进行手动赋值操作。
class Dog {
name: string
age: number
constructor(name: string, age: number) {
this.age = age
this.name = name
}
sayHi() {
console.log('Hi')
}
}
let dog = new Dog('富贵', 5)
console.log(dog) //Dog: {"name": "小狗","age": 5}
dog.sayHi() //hi
设置静态属性
我们也可以给类设置一些静态属性和方法,这些属性方法不需要通过实例,而可以直接通过类使用。
class Dog {
static gender: string = '雌'
static getGender() {
console.log('我的性别是' + Dog.gender)
}
}
console.log(Dog.gender) // '雌'
Dog.getGender() // '我的性别是雌'
继承
说到类就不得不说继承。继承往往可以使我们将一些公共方法或者属性进行抽离封装,减少代码复用率。
class Animal {
type: string
gender: boolean
constructor(type: string, gender: boolean) {
this.type = type
this.gender = gender
}
}
class Dog extends Animal {
age: number
constructor(gender: boolean, age: number) {
super('dog', gender)
this.age = age
}
}
let dog: Dog = new Dog(true, 5)
console.log(dog)
// {
// "type": "dog",
// "gender": true,
// "age": 5
// }
继承的过程中我们可能会对一些属性或方法进行重写操作
class Animal {
type: string
gender: boolean
constructor(type: string, gender: boolean) {
this.type = type
this.gender = gender
}
sayHi() {
console.log('动物再叫')
}
}
class Dog extends Animal {
age: number
constructor(gender: boolean, age: number) {
super('dog', gender)
this.age = age
}
sayHi() {
console.log('小狗在叫')
}
}
let dog: Dog = new Dog(true, 5)
dog.sayHi() //小狗在叫
修饰符
public(默认修饰符)
我们在正常定义类的情况下,里面的属性和方法默认都是public。也就是说默认定义的方法和属性是公开的,可以在类的内部和外部使用。
class Dog {
name: string = '小狗'
age: number = 5
sayHi() {
console.log(this.name'说Hi') //直接在类的内部使用name属性
}
}
let dog = new Dog() //Dog: {"name": "小狗","age": 5}
dog.name // 直接在类的外部使用name属性
private(私有的)
当成员被标记成private时,它就不能在声明它的类的外部访问。
class Dog {
private name: string = '小狗'
sayHi() {
console.log(this.name + '说Hi') //直接在类的内部使用name属性
}
}
let dog = new Dog() //Dog: {"name": "小狗","age": 5}
dog.sayHi() // 小狗说Hi
dog.name // Property 'name' is private and only accessible within class 'Dog'.
即使是继承的类,也是不能访问的。
class Animal {
private type: string
gender: boolean
constructor(type: string, gender: boolean) {
this.type = type
this.gender = gender
}
}
class Dog extends Animal {
age: number
constructor(gender: boolean, age: number) {
super('dog', gender)
this.age = age
console.log(this.type) //Property 'type' is private and only accessible within class 'Animal'.
}
}
protected(类私有的)
protected
与private
及其相似,但是他定义出的属性和方法是可以在被继承的类里访问的。
class Animal {
protected type: string
gender: boolean
constructor(type: string, gender: boolean) {
this.type = type
this.gender = gender
}
}
class Dog extends Animal {
age: number
constructor(gender: boolean, age: number) {
super('dog', gender)
this.age = age
console.log(this.type) //dog
}
}
readonly(只读的)
只读实现必须在类的属性定义或者constructor
里面赋值。
参数属性
我们发现上面的类里面,我们每次在构造函数constructor
里面声明一个属性时,都需要先在外面进行类型声明,然后再到构造函数上面声明形参才可以在内部进行赋值操作,但是我们完全可以使用参数属性声明类型声明这一步。
class Animal {
constructor(protected type: string, public gender: boolean) {
this.type = type
this.gender = gender
}
}
我们通过直接在构造函数上使用修饰符的方式,省略了类型声明的这一步,直接在构造函数里面进行赋值操作。
get/Set(存取器)
class Person {
constructor(public name: string, public age: number) {
this.name = name
this.age = age
}
}
let user: Person = new Person('fufu', 20)
user.age = 1000
上面代码里我们定义了一个Person类,这个类里有一个age属性,我们生成实例后可以随意修改这个年龄甚至修改到10000年,这显然是不合理的。我们可以使用get/set对属性进行存取设置。
class Person {
constructor(public name: string, private _age: number) {
this.name = name
this._age = _age
}
get getAge() {
return this._age
}
set setAge(num: number) {
if (num > 120) {
console.log('数字太大啦!')
}
}
}
let user: Person = new Person('fufu', 20)
user.setAge = 130 //数字太大啦!
console.log(user.getAge) // 20
抽象类
很多时候我们并不希望所有类都能被拿去创建实例,例如我们有一个animal类,我们只希望他被其他类继承,而不希望有人直接用它创建实例,这个时候我们就需要用到抽象类。
abstract class Animal {
constructor(public breed: string) {
this.breed = breed
}
}
class Dog extends Animal {
constructor() {
super('dog')
}
}
let animal: Animal = new Animal('dog') //Cannot create an instance of an abstract class.
let dog: Dog = new Dog()
console.log(dog.type) // 'dog'
抽象类中还可以定义抽象方法,抽象方法不包含具体实现并且必须在派生类中实现。 抽象方法的语法与接口方法相似。 两者都是定义方法签名但不包含方法体。
abstract class Animal {
constructor(protected breed: string) {
this.breed = breed
}
abstract sayHi(): void
}
class Dog extends Animal {
constructor() {
super('dog')
}
sayHi() {
console.log(this.breed + '在叫!')
}
}
let dog: Dog = new Dog()
dog.sayHi() // dog在叫!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!