首页 > 其他分享 >继承

继承

时间:2023-04-07 21:35:08浏览次数:44  
标签:name Parent 继承 原型 child 构造函数

继承有六种方法:原型链继承,构造函数继承,组合继承,原型式继承,寄生式继承,寄生组合式继承

原型链继承

原型链继承是一种继承方式,它是基于JavaScript中的原型链机制实现的。在JavaScript中,每个对象都有一个原型对象,原型对象又有自己的原型对象,直到达到顶层的Object.prototype。当我们访问一个对象的属性或方法时,如果对象本身没有这个属性或方法,JavaScript就会沿着对象的原型链向上查找,直到找到为止。

原型链继承的实现方式是,让一个对象的原型指向另一个对象,从而继承另一个对象的属性和方法。具体实现如下:

function Parent() {
this.name = 'parent';
}

Parent.prototype.sayHello = function () {
console.log('Hello, ' + this.name);
};

function Child() {}

Child.prototype = new Parent();

var child = new Child();
child.name = 'child';
child.sayHello(); // 输出 "Hello, child"

在上面的例子中,我们定义了一个Parent构造函数和一个Child构造函数。Child构造函数的原型指向了一个Parent实例,从而继承了Parent的属性和方法。当我们创建Child实例时,它会沿着原型链找到Parent的sayHello方法,并执行它。

需要注意的是,原型链继承有一些缺点。首先,它会将父类的属性和方法全部继承下来,包括一些不需要的属性和方法,这会导致子类实例的属性和方法过多,影响性能。其次,父类的属性如果是引用类型,子类实例修改这个属性会影响到其他实例。因此,原型链继承在实际开发中并不常用,通常使用组合继承或者寄生组合继承。

构造函数继承

构造函数继承是一种继承方式,它是通过在子类构造函数中调用父类构造函数来实现的。在构造函数中,通过使用call或apply方法来改变函数执行时的上下文,从而将父类的属性和方法赋值给子类。具体实现如下:

function Parent(name) {
this.name = name;
}

Parent.prototype.sayHello = function () {
console.log('Hello, ' + this.name);
};

function Child(name) {
Parent.call(this, name);
}

var child = new Child('child');
child.sayHello(); // 报错,sayHello方法不存在

在上面的例子中,我们定义了一个Parent构造函数和一个Child构造函数。Child构造函数通过调用Parent构造函数,将父类的属性和方法赋值给子类。当我们创建Child实例时,它只继承了父类的属性,而没有继承父类的原型上的方法。因此,调用child.sayHello()会报错。

为了解决这个问题,我们可以将父类的原型对象赋值给子类的原型对象,从而让子类继承父类的原型上的方法。具体实现如下:

function Parent(name) {
this.name = name;
}

Parent.prototype.sayHello = function () {
console.log('Hello, ' + this.name);
};

function Child(name) {
Parent.call(this, name);
}

Child.prototype = new Parent();

var child = new Child('child');
child.sayHello(); // 输出 "Hello, child"

在上面的例子中,我们将父类的原型对象赋值给子类的原型对象,从而让子类继承了父类的原型上的方法。当我们创建Child实例时,它沿着原型链找到了Parent的sayHello方法,并执行它。

需要注意的是,构造函数继承也有一些缺点。首先,父类的属性和方法只能通过构造函数继承,不能通过原型链继承。其次,每个子类实例都会创建一个新的父类实例,导致内存浪费。因此,构造函数继承在实际开发中也不常用,通常使用组合继承或者寄生组合继承。

组合继承

组合继承是一种继承方式,它是将原型链继承和构造函数继承结合起来的一种方式。组合继承通过在子类构造函数中调用父类构造函数,从而继承父类的属性,同时将父类的原型对象赋值给子类的原型对象,从而继承父类的原型上的方法。具体实现如下:

function Parent(name) {
this.name = name;
}

Parent.prototype.sayHello = function () {
console.log('Hello, ' + this.name);
};

function Child(name) {
Parent.call(this, name);
}

Child.prototype = new Parent();
Child.prototype.constructor = Child;

var child = new Child('child');
child.sayHello(); // 输出 "Hello, child"

在上面的例子中,我们定义了一个Parent构造函数和一个Child构造函数。Child构造函数通过调用Parent构造函数,将父类的属性赋值给子类。同时,我们将父类的原型对象赋值给子类的原型对象,并将子类原型对象的constructor属性指向Child构造函数,从而继承了父类的原型上的方法。

组合继承的优点是比较完备地解决了继承问题,既可以继承父类的属性,也可以继承父类的原型上的方法。缺点是在创建子类实例时,会调用两次父类构造函数,导致内存浪费。因此,后来又出现了一种优化的继承方式,即寄生组合继承。

寄生式继承

寄生式继承是一种继承方式,它是在组合继承的基础上进行优化的一种方式。寄生式继承通过创建一个临时的构造函数,将父类的原型对象赋值给这个构造函数的原型对象,从而继承父类的原型上的方法。具体实现如下:

function Parent(name) {
this.name = name;
}

Parent.prototype.sayHello = function () {
console.log('Hello, ' + this.name);
};

function Child(name) {
Parent.call(this, name);
}

function inheritPrototype(child, parent) {
var prototype = Object.create(parent.prototype);
prototype.constructor = child;
child.prototype = prototype;
}

inheritPrototype(Child, Parent);

var child = new Child('child');
child.sayHello(); // 输出 "Hello, child"

在上面的例子中,我们定义了一个Parent构造函数和一个Child构造函数。我们通过创建一个临时的构造函数inheritPrototype,将父类的原型对象赋值给子类的原型对象,并将子类原型对象的constructor属性指向Child构造函数,从而继承了父类的原型上的方法。

寄生式继承的优点是解决了组合继承的内存浪费问题,但缺点是代码比较复杂,可读性较差。因此,在实际开发中,我们可以使用ES6中的class关键字来实现继承,它更加简洁明了。

原型式继承

原型式继承是一种基于原型链的继承方式,在 JavaScript 中被广泛使用。它是通过创建一个新的对象,将一个已有的对象作为其原型,并向新对象添加新属性和方法来实现的。

在原型式继承中,我们可以通过 Object.create() 方法来创建一个新对象,并将其原型指向另一个对象。例如,我们可以通过以下代码创建一个新对象,其原型为一个已有的对象:

var parent = {
name: 'Parent',
sayHello: function() {
console.log('Hello, my name is ' + this.name);
}
};

var child = Object.create(parent);

在上面的代码中,我们首先定义了一个名为 parent 的对象,它有一个 name 属性和一个 sayHello 方法。然后,我们通过 Object.create() 方法创建了一个新对象 child,并将其原型指向 parent 对象。

现在,我们可以通过 child 对象访问 parent 对象的属性和方法,例如:

child.name; // 'Parent'
child.sayHello(); // 'Hello, my name is Parent'

我们还可以在 child 对象上添加新属性和方法,例如:

child.age = 10;

child.sayAge = function() {
console.log('I am ' + this.age + ' years old.');
};

child.sayAge(); // 'I am 10 years old.'

在上面的代码中,我们向 child 对象添加了一个 age 属性和一个 sayAge 方法,并在 sayAge 方法中使用了 this 关键字来引用 child 对象。

需要注意的是,虽然原型式继承可以实现对象之间的继承关系,但它也有一定的缺点。由于原型链的存在,如果我们在子对象上修改了某个属性或方法,那么它会影响到其所有的父对象和兄弟对象。因此,在使用原型式继承时需要小心谨慎,避免出现意想不到的问题。

寄生组合式继承

寄生式继承是一种基于原型式继承的模式,它的思路是创建一个仅用于封装继承过程的函数,该函数在内部以某种方式增强对象,最后返回这个对象。

在 JavaScript 中,我们可以使用寄生式继承来实现对象的继承关系。在寄生式继承中,我们首先创建一个用于封装继承过程的函数,然后在函数内部创建一个新对象,并将其原型指向另一个对象。接着,在函数内部可以对新对象添加新属性和方法,最后返回这个新对象。

以下是一个示例代码:

function createChild(parent) {
var child = Object.create(parent);

child.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};

return child;
}

var parent = {
name: 'Parent',
};

var child = createChild(parent);
child.name = 'Child';

child.sayHello(); // 'Hello, my name is Child'

在上面的代码中,我们首先定义了一个名为 createChild 的函数,它接受一个父对象作为参数,并返回一个新对象。在函数内部,我们使用 Object.create() 方法创建一个新对象 child,并将其原型指向 parent 对象。接着,我们在 child 对象上添加了一个 sayHello 方法,并在方法中使用 this 关键字来引用 child 对象。最后,我们将 child 对象返回。

需要注意的是,虽然寄生式继承可以实现对象之间的继承关系,但它也有一定的缺点。由于它的继承方式是基于原型式继承的,因此也存在原型链的问题。另外,它也会带来一些性能上的损失。因此,在实际开发中需要根据具体情况来选择合适的继承方式。

标签:name,Parent,继承,原型,child,构造函数
From: https://www.cnblogs.com/hgng/p/17297420.html

相关文章

  • C# 利用base继承父类的传参方法(全面的例子,包括虚方法和重写方法)
     显而易见,将我这段代码跑一遍就可以理解并会用了  publicinterfaceIAnimal{voidMove();}publicclassAnimal:IAnimal{publicstringName{get;set;}publicintAge{get;set;}publicAnimal(stringname,......
  • Java面向对象继承
    继承的概念继承是面向对象编程中的一个概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。子类在继承父类的同时也可以添加自己的属性和方法,从而实现代码的复用和扩展。继承是面向对象编程的三大特征之一,其他两个分别是封装和多态。继承的作用1.提高代码的......
  • Django笔记十八之save函数的继承操作和指定字段更新等实例方法
    本文首发于微信公众号:Hunter后端原文链接:Django笔记十八之save函数的继承操作和指定字段更新等实例方法这篇笔记主要介绍Django一些实例方法。什么是实例,我们知道通过filter()的一些筛选方法,得到的是QuerySet,而QuerySet取单条数据,通过索引,或者first()或者last()等......
  • UE5 蓝图子类“我的蓝图”中显示继承自父类的变量
    在如下图所示的地方,勾上"显示继承的变量"即可。注:继承自父类的变量默认是不显示的。    ......
  • 继承
    <!DOCTYPEhtml><htmllang="en"><head>  <metacharset="UTF-8">  <metahttp-equiv="X-UA-Compatible"content="IE=edge">  <metaname="viewport"content="width=d......
  • js的继承
    ES6的继承:子extends父,哪里继承哪里写一个super()代码:classParent{constructor(){   this.age=18}}classChildextendsParent{   //子继承父constructor(){   super()      //加上super(),要不然会报错   this.age=18}}leto=......
  • 黑马程序员前端-CSS三大特性:叠层性、继承性、优先级
    前端学习笔记教程不定期更新中,传送门:前端HTML第一天:什么是网页?什么是HTML?网页怎么形成?黑马程序员前端-CSS入门总结黑马程序员前端-CSS之emmet语法黑马程序员前端-CSS的复合选择器黑马程序员前端-CSS的显示模式黑马程序员前端-CSS背景上一期的CSS入门笔记没有更新完,继续更新中…今天......
  • CSS选择器优先级(CSS三大特性:层叠性、继承性、优先级)
    本博文介绍CSS三大特性之一:优先级。1规则(1)若选择器相同,则执行层叠性(层叠性:给相同的选择器设置相同的样式,则“后来居上”,后面设置的样式会覆盖前面设置的样式);(2)若选择器不同,则有优先级。2选择器权重常见的选择器权重如下表:选择器权重继承或者*(通配符)0,0,0,0标签......
  • JS的继承
         ......
  • python的类继承总结
    参考文档:https://blog.csdn.net/yilulvxing/article/details/85374142总结如下:第一种情况:子类和父类都有__init__(self)方法情况继承研究#如果子类也有init方法,那么调用父类的实例属性必须要在子类的init()方法中有这个super().__init__()【这点尤其要注意】#如果子类也有in......