申明一個(gè)類 class
class 類名 {
// class中主要包含兩個(gè)部分踱承,屬性和方法
屬性
方法
}
實(shí)例屬性和類屬性
- 實(shí)例屬性:實(shí)例化之后锻梳,也就是new之后才能用的屬性和方法
- 類屬性(靜態(tài)屬性):class本身自己直接使用的,下面是TS中的屬性修飾符
- static:靜態(tài)屬性,屬于類自身不屬于實(shí)例,只有自身可以訪問到
- readonly:只讀屬性九妈,只允許讀取,不允許修改
- public:所有屬性的默認(rèn)屬性雾鬼。隨意讀寫
- private:申明是一個(gè)私有屬性允蚣,不允許在外部訪問
- protected:和private基本一樣,也是不允許在外部訪問呆贿,但是允許在子 類中訪問
- demo
class Person { // 定義實(shí)例屬性 name:string = '景天'; // 在屬性前使用static關(guān)鍵字可以定義類屬性 static age:number = 18; // 定義實(shí)例方法 sayHello() { console.log('Hello') } // 定義類方法 static sayHi() { console.log('Hi') } } // 實(shí)例屬性和方法的使用 class p = new Person() console.log(p.name) p.sayHello() // 類屬性和方法的使用 console.log(Person.age) Person.sayHi()
class中的構(gòu)造函數(shù)(constructor)
- 常規(guī)寫法
class Person { name: string age: number // constructor 被稱為構(gòu)造函數(shù) // 構(gòu)造函數(shù)會(huì)在實(shí)例對(duì)象創(chuàng)建的時(shí)候調(diào)用 constructor(name:string,age:number) { // 在實(shí)例方法中,this就是表示當(dāng)前的實(shí)例 // 在構(gòu)造函數(shù)中森渐,當(dāng)前對(duì)象就是當(dāng)前新建的那個(gè)對(duì)象 // 可以通過this向新建的對(duì)象中添加屬性 this.name = name this.age = age } sayHi() { // 在實(shí)例方法中做入,可以通過this來表示當(dāng)前調(diào)用方法的對(duì)象 console.log(this) console.log(`你好,我是${this.name}`) } } class p = new Person('景天'同衣,18) console.log(p.name,p.age)
- 簡寫方式
class Person { // 可以把屬性的定義寫到構(gòu)造函數(shù)的參數(shù)中去竟块,所示一種語法糖的寫法 constructor(public name:string, public age:number) { } sayHi() { console.log(`你好,我是${this.name}`) } } class p = new Person('景天'耐齐,18) console.log(p.name,p.age)
class中的繼承
- 使用繼承后浪秘,子類將會(huì)擁有父類所有的方法和屬性蒋情。
- 如果子類中和父類中有相同的屬性和方法,子類中會(huì)覆蓋父類的方法耸携。
- 使用:
子類 extends 父類
- demo
// 創(chuàng)建一個(gè)父類 class Animal { name: string constructor(name:string) { this.name = name } sayHi() { console.log('動(dòng)物們說Hi') } } // 狗這個(gè)子類繼承父類 class Dog extends Animal { age: number constructor(name:string,age:number) { // 如果在子類中寫了構(gòu)造函數(shù)棵癣,在子類的構(gòu)造函數(shù)中必須要調(diào)用下父類的構(gòu)造函數(shù) // super就是代表父類中的構(gòu)造函數(shù) super(name); this.age = age } // 添加一個(gè)自己的方法 run() { console.log('我在跑呢') } } // 貓這個(gè)子類繼承父類 class Cat extends Animal { // 子類中也有sayHi方法,會(huì)覆蓋父類中的方法嘁酿,使用自己的方法 sayHi() { console.log('喵喵喵喵') } } let dog = new Dog('哮天犬',1000) dog.sayHi() dog.run() let cat = new Cat('九命貓妖') cat.sayHi()
抽象類和抽象方法
- 抽象類:用abstract開頭留晚,這代表是一個(gè)抽象類乾翔,抽象類和其他類的區(qū)別不大,只是不能用來創(chuàng)建對(duì)象河劝。
- 抽象方法:同樣abstract開頭,抽象方法只能定義在抽象類中矛紫,并且子類中必須對(duì)抽象方法進(jìn)行重寫赎瞎。
- demo
// 創(chuàng)建一個(gè)父類 /* 我們之前創(chuàng)建的父類,除了可以被繼承颊咬,自己也可以實(shí)例化务甥,但是有時(shí)候我們就想申明一個(gè)父類,不允許實(shí)例化贪染。 那么可以用abstract開頭缓呛,這代表是一個(gè)抽象類,抽象類和其他類的區(qū)別不大杭隙,只是不能用來創(chuàng)建對(duì)象哟绊。 可以說抽象類就是用來創(chuàng)建父類給子類繼承的。 抽象類中可以添加抽象方法痰憎。 */ abstract class Animal { name: string constructor(name:string) { this.name = name } // 定義一個(gè)抽象方法票髓,同樣abstract開頭,沒有方法體铣耘。 // 抽象方法只能定義在抽象類中洽沟,并且子類中必須對(duì)抽象方法進(jìn)行重寫。 // void:空值 abstract sayHi():void } class Dog extends Animal { sayHi() { console.log("汪汪汪") } } let a = new Animal() // 這樣就會(huì)報(bào)錯(cuò)蜗细,因?yàn)椴辉试S實(shí)例化
接口
- 和抽象類相比
- 抽象類的屬性值可以是有值得也可以是沒值裆操,接口的屬性值都是沒值的,只定義結(jié)構(gòu)炉媒,不考慮實(shí)際值
- 接口中所有的方法都是抽象方法踪区。
- 使用抽象類,是用extends繼承吊骤,可以繼承父類的方法缎岗,也可以重寫。接口是使用implements白粉,而且必須滿足接口中所有要求
- demo
// 定義一個(gè)接口 interface myInter { name: string sayHello():void } // 定義一個(gè)類去實(shí)現(xiàn)上面的接口传泊,必須滿足接口的所有要求 class Myclass implements myInter { name:string constructor(name:string) { this,name = name } sayHello() { console.log('Hello') } } // 接口如何擴(kuò)展呢鼠渺?可以使用extends擴(kuò)展,但是原來的不會(huì)改變 interface myInter2 extends myInter { age: number } // 需要注意的一點(diǎn)是眷细,接口是允許重復(fù)的拦盹,并不會(huì)覆蓋,而是會(huì)合并 // 下面這樣的薪鹦,obj就會(huì)有兩個(gè)屬性name和age interface obj { name: string } interface obj { age: number }
屬性的封裝
- 應(yīng)用場(chǎng)景:有時(shí)候我們不想屬性簡單的暴露出去掌敬,也不想被隨意更改
- 簡單的封裝
class Person { /* TS可以在屬性前面添加修飾符 - static:靜態(tài)屬性,屬于類自身不屬于實(shí)例池磁,只有自身可以訪問到 - readonly:只讀屬性奔害,只允許讀取,不允許修改 - public:所有屬性的默認(rèn)屬性地熄。隨意讀寫 - private:申明是一個(gè)私有屬性华临,不允許在外部訪問 - protected:和private基本一樣,也是不允許在外部訪問端考,但是允許在子類中訪問 */ // 私有化兩個(gè)屬性 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 { // 私有化兩個(gè)屬性 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