理解经典继承和原型继承的区别 [英] Understanding the difference between classical and prototypal inheritance

查看:62
本文介绍了理解经典继承和原型继承的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的一周里,我一直在试图理解基于类的继承和原型继承之间的区别.使用过 PHP 和 JavaScript 后,我​​希望能很快掌握这一点,但我无法理解这一点 - 我总觉得我错过了一些东西.

For the past week I've been trying to understand the difference between class based and prototypical inheritance. Having worked with PHP and JavaScript, I expected to grasp this rather quickly, but I just can't wrap my head around this – I always have the feeling that I miss something.

我了解到类就像定义对象特征的蓝图.当一个类被实例化时,根据蓝图构造一个对象.当继承发挥作用时,只能完全采用蓝图,但可以覆盖方法.

I've learned that a class is like a blueprint defining an object's characteristics. When a class is instantiated, an object is constructed according to the blueprint. When inheritance comes into play, the blueprint can only be adopted completely but methods can be overridden.

那么什么是原型呢?它是不是也一个蓝图,但已经实现(因此得名原型")?那么使用继承,只能指向已经存在的函数?

But what is a prototype then? Isn't it also like a blueprint, but already implemented (hence the name "prototype")? So with inheritance, you can only point to already existing functions?

以下内容可能看起来很愚蠢,但这就是我试图理解事物的方式.

用更人性化的术语:一个类可以被视为架构计划,一旦它被实例化,小工人就会开始根据该计划构建一个对象.为了继承某些东西,除了新的细节(可能会取代现有的细节)之外,还要重新构建完整的计划.

In more human terms: A class can be regarded as architectural plan, as soon as it get's instantiated small workers start building an object according to that plan. To inherit something, the complete plan is built again, in addition to new details (that may replace existing details).

有了原型,工作人员开始复制一个已经存在的对象并开始查看它的主要特征(存储在称为原型的东西上).为了从另一个对象继承,他们只是在某处放了一个标志,上面写着你在寻找函数 X?请这样——注意对象之间的差距".

With prototypes, the workers instead start copying an already existing object and start looking at it's main characteristics (stored on something called the prototype). To inherit from another object, they just put a sign somewhere saying "You are looking for function X? Please this way – mind the gap between objects".

这种区分是否正确?

推荐答案

在我看来,您实际上已经明白了.

It seems to me that you actually already got the point.

基于类的面向对象

正如您已经提到的,在基于类的面向对象语言(如 Java)中,类是每个未来对象的蓝图.对于对象的实例化,蓝图(您创建的类)会为该对象复制.这意味着,如果您在实例化对象后更改类,先前创建的对象将不会发生更改.

As you already mentioned, in class-based object oriented languages (like Java) a class is a blueprint for every future object. For the instantiation of an object the blueprint (the class you created) gets copied for this object. This means that in case you change the class after you instantiate your object the previously created object won't have that changes.

说到继承:假设您有一个 Person 类.您想创建另一个继承自 Person 的类 Student.Student 基本上是蓝图 Person 的副本,可以扩展蓝图的功能.所以你的例子非常准确!这在复杂但相当静态的 OO 结构中非常有用!

When it comes to inheritance: Let's say you have a class Person. You want to create another class Student that inherits from Person. Student is basically a copy of the blueprint Person which can extend the functionality of the blueprint. So your example is very accurate! This is very useful in complex but rather static OO-structures!

基于原型

基于原型的语言(如 JavaScript)不遵循这种模板化方法.你的例子再次击中了它.您基本上只是创建一个对象并引用另一个对象(您的原型).您放入原型中的所有功能将由引用该原型对象的所有对象共享.但是,重要的是要了解您不制作蓝图或模板的副本.你总是在处理对象.

Prototype based languages like JavaScript don't follow this templating kind of approach. Your example hit it pretty good again. You basically just create an object and reference to another object (your prototype). All the functionality you put in your prototype will be shared by all the objects that reference to that prototype object. However, it is important to understand that you don't make copies of blueprints or templates. You are always working with objects.

所以你可以创建一个 Person 对象.那持有像sayHello"这样的方法.如果您创建具体的人,例如Joe,您只需创建另一个对象并将其链接到 Person 对象.因此,如果您尝试 Joe.sayHello(),它将查看 Joe 对象的属性,但找不到 sayHello 方法,因此它将跳转到具体的 Person 对象.就像你说的例子.

So you could create a Person Object. That holdsmethods like "sayHello". If you create concrete person e.g. Joe you just create another object and link it to the Person object. So if you try Joe.sayHello() it will look through the Joe object properties and won't find the sayHello method so it will jump over to the concrete Person object. Just like you said with your example.

我不太喜欢基于原型的语言中的表达式继承,因为它实际上并不存在.您无需复制蓝图并扩展其功能.继承基本上通过将对象链接在一起来工作.比如上面的例子.你可以有一个 Person 对象.每个普通的人对象(例如乔)都有一个人对象作为原型.现在您创建了一个以 Person 为原型的 Student 对象.另一个对象(例如 StudentJoe)可以将 Student 作为原型.因此,它可以通过链条一直到人员访问其方法.简而言之;):基于原型的语言仅适用于链接在一起的具体对象(原型),而不适用于蓝图和模板.这种方法的优点是动态的(这就是为什么这种方法在网络中常用的原因).由于您从不使用模板,而是使用具体对象,因此原型链中的每一次更改都会对每个对象产生影响(就可访问的功能而言)——无论它是何时创建的.

I don't really like the expression inheritance in prototype based languages because it does not really exist. You don't make a copy of a blueprint and extend its functionality. Inheritance basically works by chaining objects together. For instance the example above. You can have a Person object. Every regular person object (e.g. Joe) has the Person Object as a prototype. Now you create a Student object which has the Person as a prototype. Another object (e.g. StudentJoe) can have Student as a prototype. So it can go through the chain all the way up to person to access its methods. To keep it short ;): prototype based languages only work with concrete objects which are linked together (prototypes) and not with blue prints and templates. The advantage of this approach is being dynamic (that's why this approach is commonly used in the web). As you never work with templates but with concrete objects every change in the prototype-chain will always have effect on every object (in terms of accessable functionality) - no matter when it was created.

我希望这有帮助.有一本好书叫你不懂 JavaScript - 这&对象原型很好地解释了这个基于 JavaScript 的主题.

I hope this helped. There is a good book called You don't know JavaScript - this & object prototype which explains this topic based on JavaScript really well.

这篇关于理解经典继承和原型继承的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆