类的多态:
重载和重写
- 重载
- java中的重载:函数名相同,但参数类型,数量不同或返回值不一样,这相当于把一个函数重载了(参数不同,一个方法当多个使用)
- js中没有类似java这种的重载机制。js中是根据传参不同,实现不同的业务逻辑(严格说js没有重载)
- 重写:子类重写父类上的方法
继承
子类继承父类中的属性和方法
js中的继承机制和其他后台语言是不一样的,有自己独特的处理方式
-
1.原型继承
让B子类继承A父类
实现方案:子类的原型指向父类的一个实例
特点:
- 不会把父类中的方法克隆一份给子类,而是建立了子类和父类之间的原型链查找机制
- 重定向子类的原型后,默认丢失了原本的constructor属性(或者原本在原型上的设置的属性和方法)
- 子类或子类的实例,可以基于原型链“肆意”修改父类上的属性方法,对父类造成一些“不必要的破坏”
- 会把父类中私有属性方法作为子类公有的属性方法继承过来(父类中不管是公有还是私有,最后都变为子类公有的,这样不好)
function A(){
this.x=100
}
A.prototype.getX=function getX(){
console.log(this.x)
}
function B(){
this.y = 200
}
// 让B的原型指向new A的实例,这样new B的实例既可以访问B的,也可访问A的
B.prototype = new A
B.prototype.getY=function getY(){
console.log(this.y)
}
let b = new B
2. call继承
把父类当做普通函数执行,让其执行时方法中this变为子类的实例即可
特点:
- 只能继承父类中的私有属性(继承的私有属性赋值给子类实例的私有属性),而且是类似拷贝过来一份,而不是链式查找。
- 因为只是把父类当做普通方法执行,所以父类原型上的公有属性方法无法被继承过来
function A(){
this.x=100
}
A.prototype.getX=function getX(){
console.log(this.x)
}
function B(){
// call继承
A.call(this) // 此时this.x=100 相当于 b.x=100
this.y = 200
}
B.prototype.getY=function getY(){
console.log(this.y)
}
let b = new B
3. 寄生组合继承:call继承 + 变异版的原型继承共同完成
call继承实现:私有到私有
原型继承实现:公有到公有
function A(){
this.x=100
}
A.prototype.getX=function getX(){
console.log(this.x)
}
function B(){
A.call(this)
this.y = 200
}
B.prototype = Object.create(A.prototype)
B.prototype.constructor = B // 设置B的constructor
B.prototype.getY=function getY(){
console.log(this.y)
}
let b = new B
Object.create(obj): 创建一个空对象,让其__proto__指向obj(把obj作为空对象的原型)
4. ES6创建类用class
- extends 继承和寄生组合继承基本类似
- 一旦使用extents实现继承,只要自己写了constructor,就必须写super,否则报错
- super 类似 A.call(this)
class A{
constructor(){
this.x = 100
}
// 设置私有属性,这样和在构造函数中的this.xxx = xxx 没区别(ES7)
num = 100
// 设置到A.prototype上的方法
getX(){
console.log(this.x)
}
// 把A当做普通函数对象设置的属性和方法
static n = 200
static getN(){}
}
// extends 继承和寄生组合继承基本类似
class B extends A {
constructor(){
//一旦使用extents实现继承,只要自己写了constructor,就必须写super,否则报错
// super 类似 A.call(this)
super()
this.y = 100
}
getY(){
console.log(this.y)
}
}
console.log(new A) // {x:100,num:100}
真实项目中使用继承的地方
-
react 中创建类组件
class Vote extends React.Component{} -
自己写插件或类库的时候
例如自己封装一个组件,需要用到公共的属性方法时,可以继承过来使用