经典继承与javascript中的原型继承
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了经典继承与javascript中的原型继承,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7352字,纯文字阅读大概需要11分钟。
内容图文
![经典继承与javascript中的原型继承](/upload/InfoBanner/zyjiaocheng/715/75ce06b30e314ee3b0429776a047a63b.jpg)
我搜索了这么多链接,并且不能很好地了解经典继承和原型继承之间的区别?
我从中学到了一些东西,但我仍然对这些概念感到困惑.
> Benefits of prototypal inheritance over classical?
> http://aaditmshah.github.io/why-prototypal-inheritance-matters/
经典继承
// Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
}
//superclass method
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info("Shape moved.");
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); //call super constructor.
}
//subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
经典继承是否在内部使用原型继承?
http://aaditmshah.github.io/why-prototypal-inheritance-matters/
从上面的链接,我了解到我们不能在运行时在经典继承中添加新方法.它是否正确?但是你可以查看上面的代码我可以在运行时通过原型添加“move”方法和任何方法.那么这是基于原型的经典继承吗?如果是这样,什么是实际的经典继承和原型继承?我很困惑.
原型继承.
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.area = function () {
var radius = this.radius;
return Math.PI * radius * radius;
};
Circle.prototype.circumference: function () {
return 2 * Math.PI * this.radius;
};
var circle = new Circle(5);
var circle2 = new Circle(10);
这类似于经典继承吗?我对什么是原型继承感到困惑?什么是经典继承?为什么经典继承不好?
你能给我一个简单的例子,以便以一种简单的方式更好地理解这些.
谢谢,
湿婆
解决方法:
您在问题中演示的代码示例都使用了原型继承.实际上,您使用JavaScript编写的任何面向对象的代码都是原型继承的范例. JavaScript根本没有经典继承.这应该清楚一点:
Inheritance
|
+-----------------------------+
| |
v v
Prototypal Classical
|
+------------------------------+
| |
v v
Prototypal Pattern Constructor Pattern
正如您所看到的,原型继承和经典继承是两种不同的继承范式. Self,Lua和JavaScript等语言支持原型继承.但是,大多数语言如C,Java和C#都支持经典继承.
面向对象编程的快速概述
原型继承和经典继承都是面向对象的编程范例(即它们处理对象).对象只是抽象,它封装了现实世界实体的属性(即它们代表程序中的真实单词).这被称为抽象.
抽象:计算机程序中现实世界事物的表现.
从理论上讲,抽象被定义为“通过从特定示例中提取共同特征而形成的一般概念”.但是为了这个解释,我们将使用上述定义.
现在有些对象有很多共同点.例如,泥巴自行车和哈雷戴维森有很多共同之处.
泥地自行车:
哈利戴维森:
泥巴自行车和哈雷戴维森都是自行车.因此,自行车是泥浆自行车和哈雷戴维森的概括.
Bike
|
+---------------------------------+
| |
v v
Mud Bike Harley Davidson
在上面的例子中,自行车,泥地自行车和哈雷戴维森都是抽象的.然而,自行车是泥地自行车和哈雷戴维森的更普遍的抽象(即泥地自行车和哈雷戴维森都是特定类型的自行车).
泛化:更具体抽象的抽象.
在面向对象的编程中,我们创建对象(它是真实世界实体的抽象),我们使用类或原型来创建这些对象的泛化.通过继承创建泛化.自行车是泥骑自行车的概括.因此泥巴自行车继承自行车.
经典的面向对象编程
在经典的面向对象编程中,我们有两种类型的抽象:类和对象.如前所述,对象是现实世界实体的抽象.另一方面,类是对象或另一类的抽象(即它是一种泛化).例如,考虑:
+----------------------+----------------+---------------------------------------+
| Level of Abstraction | Name of Entity | Comments |
+----------------------+----------------+---------------------------------------+
| 0 | John Doe | Real World Entity. |
| 1 | johnDoe | Variable holding object. |
| 2 | Man | Class of object johnDoe. |
| 3 | Human | Superclass of class Man. |
+----------------------+----------------+---------------------------------------+
正如您在经典的面向对象编程语言中所看到的,对象只是抽象(即所有对象的抽象级别为1),而类只是泛化(即所有类的抽象级别都大于1).
经典的面向对象编程语言中的对象只能通过实例化类来创建:
class Human {
// ...
}
class Man extends Human {
// ...
}
Man johnDoe = new Man();
在经典的面向对象编程语言中,对象是现实世界实体的抽象,而类是概括(即对象或其他类的抽象).
因此,随着抽象级别的增加,实体变得更加通用,并且随着抽象级别的降低,实体变得更加具体.在这个意义上,抽象级别类似于从更具体的实体到更一般的实体的范围.
原型面向对象编程
原型面向对象编程语言比传统的面向对象编程语言简单得多,因为在原型面向对象编程中我们只有一种类型的抽象(即对象).例如,考虑:
+----------------------+----------------+---------------------------------------+
| Level of Abstraction | Name of Entity | Comments |
+----------------------+----------------+---------------------------------------+
| 0 | John Doe | Real World Entity. |
| 1 | johnDoe | Variable holding object. |
| 2 | man | Prototype of object johnDoe. |
| 3 | human | Prototype of object man. |
+----------------------+----------------+---------------------------------------+
正如您在原型面向对象编程语言中所看到的,对象是现实世界实体(在这种情况下它们简称为对象)或其他对象的抽象(在这种情况下,它们被称为抽象的那些对象的原型).因此原型是一种概括.
原型面向对象编程语言中的对象可以创建为ex-nihilo(即无中生有)或来自另一个对象(它成为新创建的对象的原型):
var human = {};
var man = Object.create(human);
var johnDoe = Object.create(man);
在我看来,原型面向对象编程语言比传统的面向对象编程语言更强大,因为:
>只有一种抽象类型.
>概括只是对象.
到目前为止,你必须意识到经典继承和原型继承之间的区别.经典继承仅限于从其他类继承的类.然而,原型继承不仅包括从其他原型继承的原型,还包括从原型继承的对象.
原型类同构
您必须注意到原型和类非常相似.确实如此.他们是.实际上它们非常相似,您实际上可以使用原型来建模类:
function CLASS(base, body) {
if (arguments.length < 2) body = base, base = Object.prototype;
var prototype = Object.create(base, {new: {value: create}});
return body.call(prototype, base), prototype;
function create() {
var self = Object.create(prototype);
return prototype.hasOwnProperty("constructor") &&
prototype.constructor.apply(self, arguments), self;
}
}
使用上面的CLASS函数,您可以创建看起来像类的原型:
var Human = CLASS(function () {
var milliseconds = 1
, seconds = 1000 * milliseconds
, minutes = 60 * seconds
, hours = 60 * minutes
, days = 24 * hours
, years = 365.2425 * days;
this.constructor = function (name, sex, dob) {
this.name = name;
this.sex = sex;
this.dob = dob;
};
this.age = function () {
return Math.floor((new Date - this.dob) / years);
};
});
var Man = CLASS(Human, function (Human) {
this.constructor = function (name, dob) {
Human.constructor.call(this, name, "male", dob);
if (this.age() < 18) throw new Error(name + " is a boy, not a man!");
};
});
var johnDoe = Man.new("John Doe", new Date(1970, 0, 1));
但事实并非如此(即你不能使用类来模拟原型).这是因为原型是对象,但类不是对象.它们是完全不同的抽象类型.
结论
总之,我们了解到抽象是“通过从特定示例中提取共同特征而形成的一般概念”,并且泛化是“更具体抽象的抽象”.我们还了解了原型和经典继承之间的差异,以及它们如何是同一枚硬币的两个面.
在分开的说明中,我想指出原型继承有两种模式:原型模式和构造模式.原型模式是原型继承的规范模式,而构造模式用于使原型继承看起来更像经典继承.我个人更喜欢原型模式.
附:我是写博客文章“Why Prototypal Inheritance Matters”并回答问题“Benefits of prototypal inheritance over classical?”的人.我的回答是接受的答案.
内容总结
以上是互联网集市为您收集整理的经典继承与javascript中的原型继承全部内容,希望文章能够帮你解决经典继承与javascript中的原型继承所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。