super的两个应用
用法1:在子类的构造函数中使用 super,就表示用来调用父类构造函数
class animal {
public gender: string
public age: number
public weight: number
constructor(gender: string, age: number, weight: number) {
this.gender = gender
this.age = age
this.weight = weight
}
public sleep() {
console.log('动物都要睡觉')
}
}
class rabbit extends animal {
public name: string
public type: string
constructor(name: string, type: string, gender: string, age: number, weight: number) {
// 关键点
super(gender, age, weight)
this.name = name
this.type = type
}
}
编译成 JS 源码后 可以看到:就是采用 JS 原型中的借用构造函数来实现的
var _this = _super.call(this, gender, age, weight) || this;
用法2:在子类重写的方法中调用父类同名方法,super.重写的方法
class animal {
public gender: string
public age: number
public weight: number
constructor(gender: string, age: number, weight: number) {
this.gender = gender
this.age = age
this.weight = weight
}
protected sleep() {
console.log('动物都要睡觉')
}
}
class rabbit extends animal {
public name: string
public type: string
constructor(name: string, type: string, gender: string, age: number, weight: number) {
super(gender, age, weight)
this.name = name
this.type = type
}
// 重写父类方法
public sleep() {
super.sleep()
console.log('兔子在洞穴里睡觉')
}
}
此外方法重写还有一些要求
- 和父类方法同名
- 参数和父类相同,如果是引用类型的参数,需要依据具体类型来定义
- 父类方法不能是private
源码解析
ts转换成js后:
// 继承方法
var __extends = (this && this.__extends) || (function () {
// 这个方法是继承父类静态属性和方法
var extendStatics = function (d, b) {
/**
有三种方法可以实现,一种是es6写法,Object.setPrototypeOf
第二种是d._proto_= b,第三种就是通过for,in循环
**/
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
//这个就是寄生继承,继承父类原型链,有意思的是这个逗号表达式用法,学到了
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
// 等价于
// if(b) {
// _.prototype = b.prototype
// d.prototype = new _()
// }else {
// d.prototype = Object.create(b)
// }
};
})();
// 父类
var animal = /** @class */ (function () {
function animal(gender, age, weight) {
this.gender = gender;
this.age = age;
this.weight = weight;
}
animal.prototype.sleep = function () {
console.log('动物都要睡觉');
};
return animal;
}());
// 子类
var rabbit = /** @class */ (function (_super) {
// 先调用继承方法,继承父类
__extends(rabbit, _super);
function rabbit(name, type, gender, age, weight) {
// 借用父类构造函数,进行赋值
var _this = _super.call(this, gender, age, weight) || this;
_this.name = name;
_this.type = type;
return _this;
}
return rabbit;
}(animal));