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:
我是父亲
我是儿子