申明一个类 class
class 类名 {
// class中主要包含两个部分,属性和方法
属性
方法
}
实例属性和类属性
class中的构造函数(constructor)
- 常规写法
class Person {
name: string
age: number
// constructor 被称为构造函数
// 构造函数会在实例对象创建的时候调用
constructor(name:string,age:number) {
// 在实例方法中,this就是表示当前的实例
// 在构造函数中,当前对象就是当前新建的那个对象
// 可以通过this向新建的对象中添加属性
this.name = name
this.age = age
}
sayHi() {
// 在实例方法中,可以通过this来表示当前调用方法的对象
console.log(this)
console.log(`你好,我是${this.name}`)
}
}
class p = new Person('景天',18)
console.log(p.name,p.age)
- 简写方式
class Person {
// 可以把属性的定义写到构造函数的参数中去,所示一种语法糖的写法
constructor(public name:string, public age:number) {
}
sayHi() {
console.log(`你好,我是${this.name}`)
}
}
class p = new Person('景天',18)
console.log(p.name,p.age)
class中的继承
- 使用继承后,子类将会拥有父类所有的方法和属性。
- 如果子类中和父类中有相同的属性和方法,子类中会覆盖父类的方法。
- 使用:
子类 extends 父类
- demo
// 创建一个父类
class Animal {
name: string
constructor(name:string) {
this.name = name
}
sayHi() {
console.log('动物们说Hi')
}
}
// 狗这个子类继承父类
class Dog extends Animal {
age: number
constructor(name:string,age:number) {
// 如果在子类中写了构造函数,在子类的构造函数中必须要调用下父类的构造函数
// super就是代表父类中的构造函数
super(name);
this.age = age
}
// 添加一个自己的方法
run() {
console.log('我在跑呢')
}
}
// 猫这个子类继承父类
class Cat extends Animal {
// 子类中也有sayHi方法,会覆盖父类中的方法,使用自己的方法
sayHi() {
console.log('喵喵喵喵')
}
}
let dog = new Dog('哮天犬',1000)
dog.sayHi()
dog.run()
let cat = new Cat('九命猫妖')
cat.sayHi()
抽象类和抽象方法
接口
- 和抽象类相比
- 抽象类的属性值可以是有值得也可以是没值,接口的属性值都是没值的,只定义结构,不考虑实际值
- 接口中所有的方法都是抽象方法。
- 使用抽象类,是用extends继承,可以继承父类的方法,也可以重写。接口是使用implements,而且必须满足接口中所有要求
- demo
// 定义一个接口
interface myInter {
name: string
sayHello():void
}
// 定义一个类去实现上面的接口,必须满足接口的所有要求
class Myclass implements myInter {
name:string
constructor(name:string) {
this,name = name
}
sayHello() {
console.log('Hello')
}
}
// 接口如何扩展呢?可以使用extends扩展,但是原来的不会改变
interface myInter2 extends myInter {
age: number
}
// 需要注意的一点是,接口是允许重复的,并不会覆盖,而是会合并
// 下面这样的,obj就会有两个属性name和age
interface obj {
name: string
}
interface obj {
age: number
}
属性的封装
- 应用场景:有时候我们不想属性简单的暴露出去,也不想被随意更改
- 简单的封装
class Person {
/*
TS可以在属性前面添加修饰符
- static:静态属性,属于类自身不属于实例,只有自身可以访问到
- readonly:只读属性,只允许读取,不允许修改
- public:所有属性的默认属性。随意读写
- private:申明是一个私有属性,不允许在外部访问
- protected:和private基本一样,也是不允许在外部访问,但是允许在子类中访问
*/
// 私有化两个属性
private _name:string
private _age: number
constructor(name:string,age:number) {
this._name = name;
this._age = age;
}
// 提供给外界访问和修改私有属性的方法
getName() {
return this._name
}
setName(value:string) {
this._name = value
}
getAge() {
return this._name
}
setAge(value:number) {
if(value > 0) {
this._age = value
}
}
}
let p = new Person('景天',18)
console.log(p.getName());
p.setName('雪见')
console.log(p.getAge());
p.setAge(17)
- 存取器,比上面简单的封装好的多,这才是常用的方式
// 使用属性存取器
class Person {
// 私有化两个属性
private _name:string
paivate _age: number
constructor(name:string,age:number) {
this._name = name;
this._age = age;
}
// 提供给外界访问和修改私有属性的方法
get name() {
return this._name
}
set name(value:string) {
this._name = value
}
get age() {
return this._name
}
set age(value:number) {
if(value > 0) {
this._age = value
}
}
}
let p = new Person('景天',18)
console.log(p.name);
p.name = '雪见'
console.log(p.age);
p.age = 17