面向对象和基于对象的语言之间的核心区别

2022-09-01 06:56:02

我想知道两者之间的核心区别是什么

面向对象和基于对象的语言

我读过很多帖子,他们都在说两件事

  1. 面向对象的语言支持OOP的所有功能,而基于对象的语言不支持OOP的所有功能,如多态性和继承。

  2. 他们给出了javascript作为基于对象和java作为面向对象的示例

就像这个堆栈溢出的帖子

面向对象语言和基于对象的语言之间的区别

但我想知道无论使用哪种语言,这两个概念之间的核心区别是什么。

得到答案

终于得到了东西

由于Matías Fidemraizer

答案不依赖于任何语言,不依赖于任何功能,我所关注的核心差异是

本身包含对象的语言称为基于对象的语言,遵循面向对象概念的语言称为面向对象语言


答案 1

JavaScript是一种面向原型的语言。

它可以从构造函数构建实际对象,并且几乎具有任何对象可能具有的任何功能:

  • 构造 函数。
  • 方法(即JavaScript中的函数)。
  • 属性(自 ECMA-Script 5 起,“getters/setters”)。
  • 实例。

在JavaScript中,任何对象都有一个原型,包括函数。原型本身是将对象成员添加到整个对象的任何新创建的实例的基本方法。

var constructor = function() { };
constructor.prototype.text = "hello world";

alert(new constructor().text); // This alerts hello world

为什么JavaScript不是一种面向对象的编程(脚本)语言?因为它没有符合面向对象编程定义的要求的功能:

  • 多态性。您可以更改原型成员的行为,但这只是重用标识符。您无法访问伪派生对象中成员的先前实现。
  • 继承完全没有。也许原型链可以与继承相媲美,但JavaScript(ECMA-Script 5.x或更早版本)不像其他基于OOP的语言(即Java,C#,Ruby,Python,VisualBasic.NET,...)那样基于语法的继承。
  • 封装。是的,当然,但是没有办法创建实际的私有或内部对象成员。

也许我忘了提一些其他细节,但我老实说,我认为这是一个很好的总结。

更新和摘要

核心区别是面向对象的编程语言具有面向对象范式必须具有的功能,才能被视为面向对象的编程语言。因此,就目前而言,JavaScript不是一种实际的面向对象编程语言,因为它缺乏实际的多态性和继承性

更新:ES2015及以上版本是否改变了情况?

从美学上讲,是的,ES2015及以上版本有一个重大改进,让我们考虑一个不完全但更接近于面向对象的编程:语法糖调用超类

例如:

class A {
     doStuff() {
         console.log("hello world");
     }
}

class B extends A {
     doStuff() {
         super.doStuff();
         console.log("...and goodbye!");
     }
}

这是多态性。更专业的类可以重写其基类,以完全更改函数行为或执行基类已经在做的事情,从而向函数添加新代码。

顺便说一句,ES2015及更高版本仍然缺乏真正的封装:这里像私有公共这样的访问修饰符在哪里?无处可去

而且,在一天结束时,ES2015及更高版本实现了基于类的OOP,但它仍然是ECMAScript 5.x之上的语法糖层...上面的代码仍然适用于引擎盖下的原型,它的工作方式与在 ECMAScript 5.x 中编写代码的方式相同:

function A() {
}

A.prototype.doStuff = function() {
    console.log("hello world");
};

function B() {
}

B.prototype = Object.create(A.prototype);
B.prototype.doStuff = function() {
    A.prototype.doStuff.call(this);
    console.log("...and goodbye!");
};

希望我需要再次更新这个答案,因为ES2020已经提出了访问修饰符,我们将能够将JavaScript视为另一种完全支持面向对象编程的语言!


答案 2

基于对象的语言基本上包括任何提供轻松创建和使用对象的内置功能的语言。有一个主要标准:

  • 封装。对象附加了一个API,通常以这样的方式,即您更多地通过告诉它要做什么而不是在其上运行一些函数来使用对象。

    大多数基于对象的语言根据“类”来定义对象,这些类基本上是对象的蓝图。该类布置对象的内部结构并定义 API。

    不过,这并不是唯一的方法。例如,在JavaScript中,对象实际上没有“类”。任何对象都可以具有它想要的任何属性。由于函数是 JavaScript 中的一等值,因此可以将它们设置为对象的属性,并用作对象的 API。

就基于对象但不面向对象的语言而言,一个很好的例子是Visual Basic(不是.net的东西;我说的是VB6和VBA)。类存在,但不能相互继承。

面向对象的语言是基于对象的语言,它更进一步。他们内置了对 OOP 另外两个支柱的支持:

  • 遗产。对象必须能够成为(并被视为)某些其他对象的特化。这意味着,例如,能够将“狗”定义为“可以吠叫和取棍子的动物”。

    在现代语言中,它通常采用一个对象的从另一个对象的继承的形式。不过,这不是一项要求。与某些人试图告诉您的相反,OOP的定义根本不需要类。

  • 多态性。代码必须能够在不知道或关心对象的确切类型的情况下使用对象。

    大多数语言(尤其是静态类型语言)在类和继承方面定义了多态性。如果您有一个从 A 继承的类 B,则需要引用 A 的代码通常可以取 B,但不能取与 A 无关的某个类 C。Java 也有关键字,它允许您定义类必须实现的一组行为。任何类显式实现接口 X 上定义的函数的对象都有资格成为 X 类型的实例。interfaceimplements X

    其他语言,如JavaScript,允许你传递任何你喜欢的对象。只要对象呈现正确的界面,它到底是什么类型的对象并不重要。这被称为“鸭子类型”,它几乎是最纯粹的多态性形式。