「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战」
前言
从ECMAScript 2015,也就是ECMAScript 6开始,JavaScript程序员将能够使用基于类的面向对象的方式。而TypeScript增强了类的相关语法。
构造函数
class Person {
constructor(name: string) {
this.name = name
}
}
其实这里是会报错的:Property 'name' does not exist on type 'Person'.这里就需要我们在Person中标明name属性
class Person {
name: string // 'init name'
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
总而言之我们的类属性就需要先进行标明值的属性
修饰符
访问修饰符私有属性和共有属性,相信学过Java的同学都会知道
在TypeScript里,成员都默认为 public。当然你也可以明确的将一个成员标记成 public。
public
直接来个例子:
class Person {
public height: number;
public constructor(theHeight: string) {
this.height = theHeight;
}
public move(distanceInMeters: number) {
console.log(`这个人的身高是${height}cm`);
}
}
private 私有化
还是继续使用之前的Person类,我们为其添加私有类weight
class Person {
public height: number;
private weight: number;
public constructor(tHeight: number, tWeight) {
this.height = tHeight;
this.weight = tWeight
}
public move(distanceInMeters: number) {
console.log(`这个人的身高是${this.height}cm, 体重是${this.weight}kg`);
}
}
大家有的人不了解这个的会很好奇,私有类有什么特别的呢???
这里我们给大家举两个例子就知道了
1.继承
class Person {
public height: number;
private weight: number;
public constructor(tHeight: number, tWeight) {
this.height = tHeight;
this.weight = tWeight;
}
public move() {
console.log(`这个人的身高是${this.height}cm, 体重是${this.weight}kg`);
}
}
class Woman extends Person {
constructor() {
super(100, 100) // 在派生类的构造函数中必须调用 super()
}
addWeight() {
this.weight = this.weight + 10
}
addHeight() {
this.height = this.height + 10
}
}
这里我们创建了一个Woman类继承了父类Person,并实现了两个方法addWeight和addHeight,但是请看下图:
这里我们可以看见,我们在继承了
Person之后,公有的成员height是可以进行访问的,而私有成员weight访问就报错了
2.实例化
let a = new Person(100, 100);
a.height = 100
a.weight = 10;
这里我们可以看见,我们在实例化了
Person之后,公有的成员height是可以进行访问的,而私有成员weight访问就报错了
private(私有修饰符) 小结
根据两个例子:公有的成员height是可以进行访问的,而私有成员weight访问就报错了的情况,所以我们可以得出结论 当成员被标记成 private时,它就不能在声明它的类的外部访问。
protected 修饰符
protected修饰符与 private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问。但是在实例化中依然不能访问
class Person {
public height: number;
private weight: number;
protected age: number;
public constructor(tHeight: number, tWeight) {
this.height = tHeight;
this.weight = tWeight;
this.age = 18 // 永远的18岁!!!
}
public move() {
console.log(`这个人的身高是${this.height}cm, 体重是${this.weight}kg`);
}
}
class Woman extends Person {
constructor() {
super(100, 100);
}
showAge() {
console.log(this.age)
}
addHeight() {
this.height = this.height + 10;
}
}
let g = new Person(180, 75)
g.age = 19
说的没错吧亲!
readonly自读修饰符
只读属性必须在声明时或构造函数里被初始化。也就是说只能在构造函数中进行赋值的操作,其他地方就会出现报错的情况:
类中非构造函数
class Person {
readonly name: string;
public constructor() {
this.name = '-'
}
public name() {
this.name = '--'
}
}
子类中
class Woman extends Person {
constructor() {
super();
this.name = '---'
}
changeName() {
this.name = 1
}
}
实例化
使用修饰符对构造函数进行声明
如果我们使用修饰符对构造函数进行赋值的话,会出现无法继承,无法被实例化的情况(构造函数默认为public)假设我们做出了如下的操作
-
构造函数 设置为
privateclass Person { private constructor() { console.log(1) } }-
继承失败了
class Woman extends Person { constructor() { super(); } }
就会出现无法继承的情况,报错如图:
-
实例化失败了
let g = new Person()就会出现无法实例化的情况,报错如图:
-
-
构造函数 设置
protectedclass Person { protected constructor() { console.log(1) } }-
继承 是可以正常 继承的
class Woman extends Person { constructor() { super(); } }
- 实例化失败了
let g = new Person() ``` -
- 构造函数设置
readonly直接报错了亲!
抽象类
抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。 abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。
抽象类书写:
abstract class Person {
abstract ask(): void; // // 必须在派生类中实现
run(): void {
console.log('跑起来,点赞,评论,一键三连');
}
}
抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。 抽象方法的语法与接口方法相似。 两者都是定义方法签名但不包含方法体。 然而,抽象方法必须包含 abstract关键字并且可以包含访问修饰符。
实例化抽象类
let g = new Person()
继承抽象类
如果不实现抽象类中的抽象成员
class Woman extends Person {
}
总结
本章,我们遇到了类的构造函数、修饰符已经抽象类,也知道了个个修饰符对构造函数的作用以及影响,还有抽象类的用法,看到这里了,点个赞再走吧!