1、多態
其實感覺就像是js的構造函數
// 創建一個類
class Person {
// 聲明變量
name: string;
age: number
// 創建構造函數
constructor(name: string, age: number) {
this.name = name
this.age = age
}
// 聲明方法
say() {
return '我的名字叫' + this.name + ',今年' + this.age + '歲!'
}
}
let p1 = new Person('李狗蛋', 23)
console.log(p1) => // Person { name: '李狗蛋', age: 23 }
let psay = p1.say()
console.log(psay) => // 我的名字叫李狗蛋,今年23歲!
2、繼承
類似JQextends,起到拓展功能作用,新的類可以繼承引用和調用extends后面的類里面的方法和屬性
// Student是新類,Person就是已經建成需要調用其內部屬性和方法的類
class Student extends Person {
school: string;
constructor(school: string) {
// Person構造函數的參數必須在此通過super()方法傳入參數,super是代指父類(基類),super()執行一遍父類的構造函數
super('王翠花', 18)
this.school = school
}
// 相當於重寫方法,如果不重寫,相當於調用Person的say(),比如我們把Student的say改成sayHi
sayHi() {
return `我的名字叫${this.name},今年${this.age}歲,先就讀於${this.school}`
}
}
let p2 = new Student('北大青鳥')
let nsay = p2.say()
// 這是重寫了say方法后打印結果,調用的是Student的say(),優先級大於Person
console.log(nsay) => // 我的名字叫王翠花,今年18歲,先就讀於北大青鳥
// 這是沒有重新say方法的打印結果,調用的是Person的say()
console.log(nsay) => // 我的名字叫王翠花,今年18歲!
3、類(構造函數)變量作用域
// 我們可以通過一些修飾符來限制lei里面變量的作用范圍(作用域)
// public => 一個類里面聲明的屬性和方法在這個類的里面和外面都可以訪問到,默認不寫,即這個模式
class Person {
public name: string;
constructor(name: string) {
this.name = name
}
}
let p3 = new Testname('孫二丫')
console.log(p3.name) => // 孫二丫
// private => 一個類里面聲明的屬性和方法只能在這個類的內部訪問
class Person {
private name: string;
constructor(name: string) {
this.name = name
}
}
let p3 = new Testname('孫二丫')
console.log(p3.name) => // 報錯
// vsCode里面我們可以看見還未打印就已經報錯:屬性“name”為私有屬性,只能在類“Testname”中訪問
// 解析文件文件直接報錯:Property 'name' is private and only accessible within class 'Testname'
// 由此可知,private的屬性只能在類里面被調用,否則無法調用
// protected => 一個類里面聲明的方法和屬性只能在類的內部和其子類能訪問
class Person {
pretected name: string;
constructor(name: string) {
this.name = name
}
}
let p3 = new Testname('孫二丫')
console.log(p3.name) => // 報錯
// vsCode里面我們可以看見還未打印就已經報錯: 屬性“name”受保護,只能在類“Testname”及其子類中訪問
// 解析文件直接報錯:Property 'name' is protected and only accessible within class 'Testname' and its subclasses
// 由此可知,pretected的屬性只能在類里面的使用
子類和基類(父類)
class Son extends Father {}
// 從這里看
Son其實就是基類Father的子類
4、readonly只讀屬性
只讀屬性必須在聲明時或構造函數里被初始化,且值不能不能被修改,和const類似。
class Person {
pretected name: string;
constructor(name: string) {
this.name = name => // 必須初始化
}
}
5、存取器
在一個類中我們將其中一個屬性用private修飾,那么,在類的外部就無法訪問到該屬性,這個時候我們可以通過getters/setters來封裝一下,以便在類的外部去訪問該屬性。需要注意的是,只帶有 get不帶有set的存取器自動被推斷為readonly。也就是說,如果只寫get但沒有set的話,我們是不能更改值的。
class Person {
private _age: number; => // 報錯,屬性“_age”沒有初始化表達式,且未在構造函數中明確賦值。
constructor() {
this._age = 0 => // 必須賦值,才不會報上面的錯
}
// 返回設置的值
/*相當於java中的getAge()*/
get age () {
return this._age
}
/*相當於java中的setAge()*/
set age (newAge: number) {
if (newAge < 0 || newAge > 150) {
console.log('對不起,你輸入的年齡不合法!')
} else {
this._age = newAge
}
}
say () {
return `我今年${this._age}歲了!`
}
}
let p4 = new Person()
p4._age = 30 => 屬性“_age”為私有屬性,只能在類“Person”中訪問
p4.age = 30
console.log(p4.say()) => //我今年30歲了!
6、靜態屬性
跟java類似,也是使用static關鍵字修飾。用static修飾的屬性會在這個類被加載的時候就進行初始化。 靜態屬性直接通過類名訪問,無需實例化。
class Person {
// 注意不要在constructor里面賦值,因為static不能修改值
static school:String = "山東藍翔";
/*參數屬性 直接給參數添加一個訪問修飾符來定義一個屬性*/
constructor(private name: String, protected age: number) {
this.name = name;
this.age = age;
}
private say() {
console.log(`${this.name},${this.age}`);
}
protected tell() {
console.log(`${this.name},${this.age}`);
}
}
Person.school;//直接通過類名訪問,無需實例化
console.log(Testschool.school) => // 只聲明屬性,未手動初始化時會自動初始化為undefined,而且正常情況下應該new一個實例,在調用
console.log(Testschool.school) => // 山東藍翔,初始化后顯示初始化的值
7、抽象類 (abstract)
abstract關鍵字是用於定義抽象類和在抽象類內部定義抽象方法,子類必須實現父類的抽象方法 ,它們不會被實例化,僅提供繼承
abstract class Father {
name: string;
age: number;
constructor() {
this.name = '李狗蛋'
this.age = 23
}
abstract say():string => 必須聲明類型,否則報錯
tell() {
console.log('這是抽象類的方法!')
}
}
class Son extends Father {
school: string;
constructor() {
super()
this.school = '學校'
}
say() {
return '這是非抽象類!'
}
}
let p5 = new Son()
p5.tell() => // 這是抽象類的方法!
console.log(p5.say()) => // 這是非抽象類!
let p6 = new Father() => // 報錯:無法創建抽象類的實例
8、重寫
class NewFather {
say() {
console.log('我是父親')
}
}
class NewSon extends NewFather {
say() {
super.say()
console.log('我是兒子')
}
}
let g: NewSon = new NewSon()
g.say() => 繼承重寫
result:
我是父親
我是兒子