JS中的多种继承方式(第12天)
//----------------JS中的多种继承方式------------------
/*
* JS本身是基于面向对象开发的编程语言
=> 类:封装、继承、多态
封装:类也是一个函数,把实现一个功能的代码进行封装,以此实现“低耦合,高内聚”
多态:重载、重写
=>重载:相同的方法名,由于参数类型/个数或者方法返回的值不同,具备了不同的功能(JS不具备严格意义上的重载,JS中的重载:同一个方法内,根据传参的不同实现不同的功能)
=>重写:子类重写父类上的方法(伴随着继承运行的)
继承:子类继承父类中的方法
继承的目的:让子类的实例同时也具备父类中的私有属性和公共的方法
*/
function Father() {
this.father_name = 'father';
this.sum = function(){
console.log(11);
}
}
Father.prototype.getName = function(){
console.log(this.name);
}
function Son(){
this.name = 'son';
}
/*
// 原型链继承:让子类的原型指向父类的实例
Son.prototype = new Father;
// 重定向原型之后记得手动补上 constructor
Son.prototype.constructor = Son;
// 原型链继特点:
// 1、父类中私有的属性和方法最后都变成了子类实例共有的
// 2、原型继承并不是把父类的属性和方法“拷贝”给子类,而是让子类实例基于__proto__原型链查找到父类和子类定义的属性和方法
// 3、子类实例基于__proto__修改子类原型上的内容,只会对子类的其他实例造成影响,并不会影响父类的实例,但是如果是修改子类原型的原型链中的内容(即 子类实例.__proto__.__proto__),这样修改的是父类的原型,那受影响的不仅是父类的实例,子类的其他实例也会受影响
*/
/*
// call继承(也叫借用构造函数继承):在子类中将父类作为普通函数执行,同时将父类中的this改为子类的实例
function Son(){
// 在子类的构造函数中把父类当做普通函数执行,将函数中的this改为子类的实例
Father.call(this);// 改变Father中的this指向
this.name = 'son';
}
// call继承的特点:
// 1、子类只能继承父类中私有的属性和方法,不能继承父类原型上的属性和方法
// 2、子类继承过来的属性也变成了子类私有的
*/
// 组合继承:原型继承 + call继承
/* function Son(){
Father.call(this);
this.sonName = 'son';
}
Son.prototype = new Father;
Son.prototype.constructor = Son;
// 组合继承的特点:
// 1、子类继承父类的私有属性变成自己的私有属性,继承公有属性和方法变成子类公有的
// 2、父类私有的属性和方法也会继承(拷贝)在子类的公有属性和方法中
// console.log(f.sum === f.__proto__.sum); // false
// !注意:这种方式会把父类的私有属性和方法同时拷贝给子类的私有和公有,且子类继承过来的私有和公用方法不是同一个(堆地址不同)
// => 子类实例.私有方法(从父类继承过来的) !== 子类实例.__proto__.方法(从父类继承过来的)
*/
/* // 寄生组合继承:在组合继承的方法上进行改进
function Son(){
Father.call(this);
this.sonName = 'son';
}
// Object.create(protoObj):创建一个空的对象,让这个空对象的__proto__指向 protoObj
Son.prototype = Object.create(Father.prototype);
Son.prototype.constructor = Son; */
/* // Object.create 的实现
Object.create = function(proto){
function anmouse(){}
anmouse.prototype = proto
return new anmouse;
}
console.log(Object.create(Son)) */
Son.prototype.getSonName = function(){
console.log(this.name)
}
let f = new Son;
let p = new Son;
// ---------- ES6中的类的继承-------------
class Person{
constructor(name) {
this.person = name;
}
// 用等号的是设置私有的方法
sum = function(){
console.log(222)
}
// 直接写的是设置公有的方法
getPerson(){
console.log(111)
}
}
// 继承:子类 extends 父类(类似于寄生组合继承)
class Per extends Person{
constructor(age) {
super('我是父类'); // !在子类的constructor第一行一定要加 super()
this.age = age;
}
}
let y = new Person('父类');
let q = new Per(12);