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 年,为了幸福生活要慎重选择!!!
喜欢这篇文章文章的小伙伴们点赞+转发支持,你们的支持是我最大的动力!