美文网首页
面向对象——继承

面向对象——继承

作者: IvyAutumn | 来源:发表于2018-12-15 17:48 被阅读0次

许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。ECMAScript只支持实现继承,而且其实现继承主要是依赖原型链来实现的。
以一个例子来说明一些知识:

function SuperType(){
    this.property = true;
}
SuperType.prototype.getSuperValue = function(){
    return this.property;
};

function SubType(){
    this.subproperty = false;
}

//继承 SuperType
SubType.prototype = new SuperType(); //new了一个SuperType类的实例

SubType.prototype.getSubValue = function(){
    return this.subproperty;
};

var instance = new SubType();
alert(instance.getSuperValue());

确定原型和实例的关系

1.使用instanceof
只要用这个操作符来测试实例与原型链中出现过的构造函数,结果就会返回true

alert(instance instanceof Object); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); //true

2.使用isPrototypeOf()
只要是原型链中出现过的原型,都可以说是该原型链所派生的实例原型。

alert(Object.prototype.isPrototypeOf(instance)); //true
alert(SuperType.prototype.isPrototypeOf(instance)); //true
alert(SubType.prototype.isPrototypeOf(instance)); //true

原型链的问题

1.包含引用类型值所带来的问题。例如

function SuperType(){
    this.colors = ["a", "b", "c"];
}

function SubType(){

}

//继承了SuperType
SubType.prototype = new SuperType();

var instance1 = new SubType();
instance1.colors.push("d");
alert(instance1.colors); //"a,b,c,d"

var instance2 = new SubType();
alert(instance2.colors); //"a,b,c,d"

结果是SubType的所有实例都会共享同一个colors属性,这不是我们想要的。
2.在创建子类型的实例时,不能向超类型的构造函数中传递参数。

以上两个问题都可以使用“借用构造函数”(也称伪造对象或经典继承)来解决

借用构造函数

  • 使用apply()和call()方法在新创建的对象上执行构造函数。重写上面的例子
function SuperType(){
    this.colors = ["a", "b", "c"];
}

function SubType(){
    //继承了SuperType
    SuperType.call(this);
      //SuperType.apply(this);
}

var instance1 = new SubType();
instance1.colors.push("d");
alert(instance1.colors); //"a,b,c,d"

var instance2 = new SubType();
alert(instance2.colors); //"a,b,c"
  • 借用构造函数的问题
    回到了构造函数模式,函数无法实现复用。

组合继承

也叫作伪经典继承。使用原型链实现对原型属性和方法的继承,通过借用函数来实现对实例属性的继承。

function SuperType(name){
    this.name = name;
    this.colors = ["a", "b", "c"];
}
SuperType.prototype.sayName = function(){
    alert(this.name);
};


function SubType(name,age){
    //继承属性
    SuperType.call(this,name);
    
    this.age = age;
}

//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    alert(this.age);
}

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("d");
alert(instance1.colors); //"a,b,c,d"
instance1.sayName();  //"Nicholas"
instance2.sayAge();  //29

var instance2 = new SubType("Greg",27);
alert(instance2.colors); //"a,b,c"
instance1.sayName();  //"Greg"
instance2.sayAge();  //27

原型式继承

ECMAScript5通过新增Object.create()方法规范化了原型式继承。该方法接受两个参数;

  • 用作新对象原型的对象
  • (可选)为新对象定义额外属性的对象
var person = {
    name: "Nicholas",
    friends: ["Shelby", "Count", "Van"]
};

var anotherPerson = Object.create(person,{
    name:{
        value: "Greg"
    }
});

alert(anotherPerson.name);  //"Greg"

注意:使用引用类型值的属性始终都会共享相应的值

寄生式继承

寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再返回对象。


最理想的继承范式——寄生组合式继承

本质上是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。寄生组合式继承的基本模式如下:

function inheritPropotype(subType,superType){
    var prototype = object(superType.prototype); //创建对象
    prototype.constructor = subType; //增强对象
    subType.prototype = prototype; //指定对象
}

该示例函数实现了寄生组合式继承最简单的形式。该函数接受两个参数:子类型构造函数和超类型构造函数。在函数内部:
1.创建超类型原型的一个副本
2.为创建的副本添加constructor属性,从而弥补因为重写原型而失去的默认constructor属性
3.将新创建的对象(即副本)赋值给子类型的原型。

function SuperType(name){
    this.name = name;
    this.colors = ["a", "b", "c"];
}
SuperType.prototype.sayName = function(){
    alert(this.name);
};


function SubType(name,age){
    //继承属性
    SuperType.call(this,name);
    
    this.age = age;
}

//继承方法
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function(){
    alert(this.age);
}

相关文章

  • JavaScript之面向对象编程

    五、面向对象编程 目录:面向对象原型继承、面向对象class继承(ES6引入的) 1.面向对象原型继承 类:模板 ...

  • 王艳华Pythonday03

    Python的面向对象 Java 面向对象 继承

  • Python面向对象继承

    面向对象继承 面向对象编程 (OOP),英语全称:Object Oriented Programming,面向对象...

  • java基础-day10-面向对象4.0

    面向对象4.0 1. 面向对象之继承 1.1 生活中的继承 1.2 Java中的继承 1.3 子类对象创建,会调...

  • 面对对象高级编程

    面向对象高级编程: 面向对象编程:封装、继承和多态 面向对象高级编程:多重继承、定制类和元类

  • Web前端经典面试试题及答案2

    javascript面向对象中继承实现? 面向对象的基本特征有:封闭、继承、多态。在JavaScript中实现继承...

  • JAVA语言第二课

    JAVA面向对象——四大特征 继承篇——extendsJava 继承继承的概念继承是java面向对象编程技术的...

  • js面向对象设计

    面向对象模式 继承

  • JavaScript 面向对象编程

    JavaScript 快速入门 面向对象编程创建对象构造函数忘记写new怎么办?原型继承class继承 面向对象编...

  • 面向对象:创建对象&继承

    博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...

网友评论

      本文标题:面向对象——继承

      本文链接:https://www.haomeiwen.com/subject/eauwhqtx.html