面向对象的继承

了解继承前最好先看一下原型那一篇文章

属性查找:1.先自身查找
2.再沿原型向上查找
3.直到原型链出口结束 Object.prototype.__ proto__

面向对象的三大特点:封装,继承,多态。
继承 :从其他对象上获得属性或方法 叫做继承

编程所说的继承来自面向对象编程语言

类别有继承关系 (子类 和 父类)

JS中没有类 class 它的本质是 function,它只是一个语法糖
class a {};
console.log(typeof a);打印结果为function
JS中的构造函数 可以被看作是类 JS也可以看作是面向对象的编程语言
JS中的构造函数的行为 非常接近 类

由浅入深的演示下继承,重点看面向对象开发的两种继承方式

1.1子类继承父类的私有属性:修改父类的执行环境 ,让父类在子类中执行

function Father(name, age, sex) {
 // 所有绑定在this关键字上的 属性  都是 '私有属性'(对象自身的属性)
    this.name = name;
    this.age = age;
    this.sex = sex;
}
// 子类应该继承父类 私有属性
// 修改父类的执行环境
// 让父类在子类中执行
function Son(name, age, sex) {
    this.f = Father;
    this.f(name, age, sex);
    delete this.f;
}
var s = new Son('zhangming', 18, 'nan');
console.log(s);

1.2从别的对象获得属性或方法:
让B的实例 获得 A的属性和方法;
通过原型来继承;
将A的实例赋值给B的原型;

function A() {
   this.a = 'aaaaa';
    this.fn = function() {
        console.log(this.a);
    }
}

function B() {
    this.a = 'bbbbbbb';
}
// 从别的对象获得属性或方法
// 让B的实例 获得 A的属性和方法
// 通过原型来继承
// 将A的实例赋值给B的原型
B.prototype = new A();
var b = new B();
console.log(b);
b.fn();//打印结果bbbbbbb

B的原型是A;
A中的属性和方法在B的原型里,还是通过属性查找的方式来访问属性和方法。
如果B对象中没有a属性,打印的结果就为aaaaa
在这里插入图片描述

1.3这也是一种继承

var obj = {
          x: 1,
           fn: function() {
               console.log(this.x);
           }
       };
var obj2 = {
          x: 2
       }
obj.fn.call(obj2); //打印结果为2   我们让obj2 借用了 obj的函数 fn

(重点:它来了,它来了)面向对象开发的两种方式,对应两种继承方式:

1.混合开发(构造函数继承+原型)–混合继承

案例:

function Father(name, age, sex) {
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
Father.prototype.play = function() {
           console.log('play');
        }

function Son(name, age, sex) {
    // 属性继承(构造函数的继承)---从父类继承属性  在子类中执行父类
    Father.call(this, name, age, sex);
}
// 方法继承(原型继承)---通过 原型 继承 公有属性
Son.prototype = new Father();//第一种方法:将父类的实例化对象赋值给子类的原型,同时修改了子类的构造函数体。
Son.prototype = Father.prototype;//第二种方法:将父类的原型赋值给子类的原型
Son.prototype.constructor=Son;//重新设置子类的构造函数体。

var s = new Son('zhangming', 20, 'nan');
 console.log(s);
 s.play();

2.ES6class开发

class是构造函数的语法糖

extends关键字:
class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

super关键字:
子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。

super关键字既可以当作函数使用,也可以当作对象使用。
第一种情况,super作为函数调用时,代表父类的构造函数。
第二种情况,super作为对象时,在普通方法中,指向父类的原型对象;

案例:

class Person {
constructor(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    showinfo() {
        return `我的姓名是${this.name},我今年${this.age}岁,我是${this.sex}的`;
    }

    info() {
        return '我是父类的方法';
    }
}
let p1 = new Person('zhangsan', 100, '男');
console.log(p1.name);
console.log(p1.showinfo());
class Student extends Person {
    constructor(name, age, sex, pro) {
          //super作为函数调用时的情况
        super(name, age, sex); //要得到与父类同样的实例属性和方法,必须先调用super方法,子类才能得到this对象
        this.pro = pro;
    }
    showinfo() {
        return super.showinfo() + ',我的专业是' + this.pro; //super当对象使用的情况
    }
}
let s1 = new Student('lisi', 2500, '女', 'web');
console.log(s1.name);
console.log(s1.showinfo());
console.log(typeof Person); //function  构造函数的语法糖
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值