首页 前端知识 《TypeScript》入门与精通 - 一文了解TS中的类

《TypeScript》入门与精通 - 一文了解TS中的类

2024-10-17 10:10:09 前端知识 前端哥 518 815 我要收藏

class Human {

protected name = “oliver”;

public getName() {

return this.name;

}

}

// 使用关键字extends

class User extends Human {

public age = 18;

public getAge() {

return this.age;

}

public getName() {

return super.name; // 正确

}

public getNameFunc() {

return this.name(); // 正确

}

}

const user = new User();

console.log(user.name); // 报错,因为name是protected,无法访问

console.log(user.getName()); // test

实例化对象中无法调用类上定义的protected的属性或方法,但是子类上是能继承的,子类中的使用和public属性没有区别,这个就是protected;

小结


总的来说:、

  • public类型:本类中可以使用,子类中可以使用,实例对象可以使用;

  • private类型:本类中可以使用,子类中不能使用,实例对象不可以使用;

  • protected类型:本类中可以使用,子类中可以使用,实例对象不可以使用;

如果还不清晰,那么看一个例子:

class Human {

protected name = “oliver”;

private sex = “男”;

public getName() {

return this.name;

}

}

// 使用关键字extends

class User extends Human {

public age = 18;

public getAge() {

return this.age; // 正确

}

public getName() {

return super.name; // 正确,因为是protected,可以被子类调用

}

public getSex() {

return super.sex; // 报错,因为是private,不能被子类调用

}

protected getNameFunc() {

return super.getName(); // 正确,因为是public

}

}

const user = new User();

console.log(user.name); // 报错,因为name是protected,能被子类调用,且无法被实例化对象调用

console.log(user.getName()); // 正确,因为是public

console.log(user.sex; // 报错,因为sex是private,无法被子类调用,也无法被实例化对象调用

构造器

=============================================================

构造器,也就是contructor,它是一种用于创建和初始化class创建的对象的特殊方法,先看个例子:

// 基本写法

class Human {

public name: string;

// 构造器

constructor(name: string) {

this.name = name;

}

}

const user = new Human(“oliver”);

console.log(user.name); // oliver

这里定义了一个类,class,它有一个私有类型的属性name,name的类型是string,并且在构造器中对其进行了初始化,初始化的值来自于new时候传入的参数,另外在TS中是可以简写的,下面这段代码和上例效果完全相同

// 简化写法

class Human {

// 构造器

constructor(public name: string) {}

}

const user = new Human(“oliver”);

console.log(user.name); // oliver

那么,子类能继承到这个属性吗,答案是可以的,先再看下面这一个例子:

class Human {

constructor(public name: string) {}

}

class User extends Human {

getName() {

return this.name;

}

}

const user = new User(“oliver”);

console.log(user.getName()); // oliver

因为是public属性,那么子类是可以继承到name属性的,这么写没问题,那么子类如果也有构造器怎么办?那么再看一个例子:

class Human {

constructor(public name: string) {}

}

class User extends Human {

constructor(public age: number, name: string) {

super(name);

}

getName() {

return this.name;

}

getAge() {

return this.age;

}

}

const user = new User(20, “oliver”);

console.log(user.getName()); // oliver

console.log(user.getAge()); // 20

这个例子中存在子类和父类,两个类都有构造器,特别的是,在子类的构造器constructor中使用了一个super函数,这就有点奇怪了,这个用法和上文中的不一样,上文的用法是super.getName()这种,这里为啥是一个函数,实际上,super在方法中使用,代表的是父类,用法就是类似于super.getName(),而在构造函数中,它就可以用作一个函数,代表的是父类的contructor函数,这样我们就可以将一些初始化的值赋予父类使用了,否则父类没办法接受实例化对象的参数;

到这里,又有一个新问题,如果父类的constructor中没有参数,那么怎么使用,实际上这种只要使用一下super就好了,比如:

class Human {}

class User extends Human {

constructor(public age: number, public name: string) {

super();

}

getName() {

return this.name;

}

getAge() {

return this.age;

}

}

const user = new User(20, “oliver”);

console.log(user.getName()); // oliver

console.log(user.getAge()); // 20

Getter和Setter

=======================================================================

getter和setter,主要用途是对私有属性进行读取和设置,可能有同学会问,这个有什么用,既然都设置成私有属性了,那么就是希望不对它进行修改,怎么说呢,实际上是不对的,私有属性的作用却是是为了不将属性直接对外暴露,但是不代表某些情况下不能对他进行修改,因此Getter和Setter还是很有必要的,直接看个例子吧:

class User {

constructor(private _age: number, private _name: string) {}

get name() {

return this._name;

}

get age() {

return this._age;

}

}

const user = new User(20, “oliver”);

console.log(user.name); // oliver

console.log(user.age); // 20

这个就是Getter的用法,例子中定义了两个私有属性_age和_name,另外定义了两个getter,分别获取这两个私有属性,就这么简单,同理Setting也是这么简单;

class User {

constructor(private _age: number, private _name: string) {}

get name() {

return this._name;

}

get age() {

return this._age;

}

set name(value: string) {

this._name = value;

}

set age(value: number) {

this._age = value;

}

}

const user = new User(20, “oliver”);

user.age = 18;

user.name = “demo”;

console.log(user.name); // demo

console.log(user.age); // 18

值得注意的是,Getter和Setter看上去好像是一个方法,但实际上是属性,因此在调用的时候不需要加括号,以及,set中设置return是不会生效的;

静态属性和静态方法

===================================================================

static,这又是一个新的关键词,在MDN上的解释:类(class)通过 static 关键字定义静态方法。不能在类的实例上调用静态方法,而应该通过类本身调用。这些通常是实用程序方法,例如创建或克隆对象的功能。

什么意思呢,简单的说,就是这个方法不能被实例调用,只能在类上调用,讲到这里,有些同学可能会问这个和protected感觉好像,但实际上,这两个可以说完全不是一个东西,举个例子

class User {

protected static name: string;

}

可以看出,私有类型和静态属性是可以并存的,这两者不是一个东西,值得注意的是,所有的访问类型,都是实例化后才生效的,也就是说,如果不实例化而是直接调用,public,private这些没有意义;

接着再说上面这段代码,真要去使用的时候会发现报错,提示:静态属性“name”与构造函数“User”的内置属性函数“name”冲突,好家伙,恭喜你,找到一个保留字,不知道为啥,我个人查了许久没有找到答案,网上流传的解释是:static下的name是一个保留词,不能使用(如果有人找到了合理的答案,记得告诉博主);

接着说static,我们还是直接看一个示例吧,题目:有一个构造函数,它只能被new一次,也就是设计模式中的单例模式,很多库文件就是基于单例模式实现的,比如VueX,VueX使用的就是单例模式,只有第一次使用的使用才会注入一个store,如果被多次Vue.use(vuex),那么它不会被多次覆盖生效,达到的效果如下

解答:

class User {

private static User: User;

private constructor() {}

static init() {

if (!this.User) {

this.User = new User();

}

return this.User;

}

}

const user1 = User.init();

const user2 = User.init();

console.log(user1 === user2); // true

只有第一次调用init的时候才会去进行new,第二次开始,都是将其已经new好的实例返回回去,这样就达到了单例模式;

只读属性

==============================================================

好吧,有一个新关键字,readonly,根据字面意思,代表着只读属性,用法也比较简单,直接看例子:

class User {

private readonly name: string;

constructor(name: string) {

this.name = name;

}

}

const user = new User(“oliver”);

user.name = “demo”; // 报错

可以看出,尝试修改的时候会直接报错,只读属性是不允许被修改的;

抽象类

=============================================================

关键字:abstract,使用abstract定义的类就是抽象类,抽象类和普通类最大的区别就是抽象类不能被实例化,也就是不能被new,比如:

abstract class Human {}

new Human(); // 报错,无法被实例化

那么抽象类的作用是什么,主要的作用是抽离贡性的东西,比如:

// 抽象类

abstract class Human {

// 抽象类中的抽象方法

abstract getSex(): string;

}

class Man extends Human {

getSex() {

return “男”;

}

}

class Woman extends Human {

getSex() {

return “女”;

}

}

我们定义了一个抽象类Human,他里面有一个抽象方法,规定了所有继承这个抽象类的类都必须包含getSex这个方法,并且这个方法返回的类型是字符串,讲到这里,有的同学可能会问,这个和接口Interface好像, 用法几乎一样,没错,是挺像的,区别在于,抽象类是对类进行共性的剥离,并且抽象类的内部也是可以存在具体实现的功能的代码的,比如:

// 抽象类

abstract class Human {

getPlace(){

return “江苏”

}

// 抽象类中的抽象方法

abstract getSex(): string;

}

class Man extends Human {

getSex() {

return “男”;

}

}

class Woman extends Human {

getSex() {

总结

  • 框架原理真的深入某一部分具体的代码和实现方式时,要多注意到细节,不要只能写出一个框架。

  • 算法方面很薄弱的,最好多刷一刷,不然影响你的工资和成功率😯

  • 在投递简历之前,最好通过各种渠道找到公司内部的人,先提前了解业务,也可以帮助后期优秀 offer 的决策。

  • 要勇于说不,对于某些 offer 待遇不满意、业务不喜欢,应该相信自己,不要因为当下没有更好的 offer 而投降,一份工作短则一年长则 N 年,为了幸福生活要慎重选择!!!

喜欢这篇文章文章的小伙伴们点赞+转发支持,你们的支持是我最大的动力!

转载请注明出处或者链接地址:https://www.qianduange.cn//article/19094.html
标签
gitubuntu
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!