面向对象的编程
面向对象的编程( OOP )是基于对象概念的编程范式,该范例可以包含数据和代码:以字段形式(通常称为属性或属性)的数据,以及以过程形式的代码(通常已知)作为方法)。
对象的一个共同特征是将方法附加到它们上,并可以访问和修改对象的数据字段。在这个OOP的品牌中,通常有一个特殊名称,例如this
是指引用当前对象的特殊self
。在OOP中,计算机程序是通过使它们与彼此相互作用的对象进行设计的。 OOP语言是多种多样的,但最受欢迎的语言是基于班级的,这意味着对像是类的实例,也决定了它们的类型。
许多使用最广泛的编程语言(例如C ++ , Java , Python等)都是多范式的,它们支持面向对象的编程或多或少,通常结合势在必行的编程,程序性编程和功能性程式设计.
重要的面向对象的语言包括: ADA , ActionScript , C ++ , Common Lisp , C# , Dart ,Eiffel, Eiffel , Fortran 2003 , Haxe , Java ,Java, JavaScript ,Kotlin, Kotlin , logo ,Matlab, Matlab , objective -c , objection -c , object R , Raku , Ruby , Scala , Simscript , Simula , Smalltalk , Swift , Vala和Visual Basic.Net 。
历史
术语以现代的面向对象的编程援引“对象”,于1950年代末和1960年代初在麻省理工学院首次露面。在1960年,在人工智能小组的环境中,“对象”可以指带有属性(属性)的确定项目( LISP原子);艾伦·凯(Alan Kay)随后列举了对LISP内部的详细理解,这是对他在1966年的思想的强烈影响,并且他早在1967年就使用了“面向对象的编程”一词。 “ ,艾伦·凯(Alan Kay)将OO的概念与对象的更传统的抽像数据类型概念区分开来,并暗示计算机科学机构没有采用他的概念。由芭芭拉·利斯科夫( Barbara Liskov)合著的1976年的麻省理工学院备忘录将Simula 67 , Clu和Alphard列为面向对象的语言,但没有提及SmallTalk。
我想到的对象像网络上的生物单元格和/或单个计算机一样,只能与消息通信(因此,消息传递在一开始就出现了- 花了一段时间才能看到如何在编程语言中进行消息,以便有效地进行消息传递有用)。
艾伦·凯(Alan Kay),
另一个早期的麻省理工学院例子是伊万·萨瑟兰(Ivan Sutherland)在1960 - 1961年创建的Sketchpad 。在1963年技术报告的词汇表中,基于他对素描板的论文,萨瑟兰定义了“对象”和“实例”的概念(由“主”或“定义”所涵盖的类概念),尽管专门针对图形交互。此外,MIT Algol版本AED-0,在数据结构(该方言中的“ plex”)和过程之间建立了直接链接,并预先配置了后来称为“消息”,“方法”和“成员函数”的内容。
Simula引入了重要的概念,如今,这些概念是面向对象的编程的重要组成部分,例如类和对象,继承和动态绑定。面向对象的模拟编程语言主要是由与物理建模有关的研究人员使用的,例如研究和改善通过货物端口的船舶及其内容的移动。
在1970年代, SmallTalk编程语言的第一版是在Xerox Parc上由Alan Kay , Dan Ingalls和Adele Goldberg开发的。 SmallTalk-72包括一个编程环境,并进行了动态键入,起初被解释了,而不是编译。 SmallTalk因其在语言级别及其图形开发环境中的对象取向而闻名。 SmallTalk经历了各种版本和对语言增长的兴趣。尽管SmallTalk受Simula 67中引入的想法的影响,但它被设计为一个完全动态的系统,可以在该系统中动态创建和修改类。
在1970年代,SmallTalk影响了LISP社区,以结合通过LISP机器引入开发人员的基于对象的技术。对LISP进行各种扩展的实验(例如引入多种继承和混合素的环和口味)最终导致了通用的LISP对象系统,该对象系统集成了功能编程和面向对象的编程,并允许通过Meta-Object协议进行延伸。在1980年代,有一些尝试设计处理器体系结构,其中包括对内存中对象的硬件支持,但它们并不成功。示例包括Intel IAPX 432和Linn Smart Rekursiv 。
1981年,戈德伯格(Goldberg)编辑了《八月》( Byte)杂志,向更广泛的观众介绍了Smalltalk和面向对象的节目。 1986年,计算机协会组织了第一次关于面向对象的编程,系统,语言和应用程序(OOPSLA)的会议,该会议出乎意料地参加了1000人。在1980年代中期,Objective-C是由Brad Cox开发的,Brad Cox在Itt Inc.使用了Smalltalk。 Bjarne Stroustrup曾使用Simula进行博士学位论文,创建了面向对象的C ++ 。 1985年,贝特兰·迈耶(Bertrand Meyer )也制作了艾菲尔语言的第一个设计。 Eiffel专注于软件质量,是一种纯粹面向对象的编程语言,并且是支持整个软件生命周期的符号。迈耶(Meyer)根据面向对象的软件构建中的软件工程和计算机科学的少数关键思想描述了Eiffel软件开发方法。埃菲尔(Eiffel)的质量重点至关重要的是迈耶(Meyer)的可靠性机制,即通过合同设计,这是方法和语言的组成部分。
在1990年代初期和中期,以对象为导向的编程作为主要的编程范式开发,当时支持该技术的编程语言广泛可用。其中包括Visual FoxPro 3.0, C ++和Delphi 。图形用户界面的普及进一步增强了其主导性,这些用户界面的普及在很大程度上依赖于面向对象的编程技术。可以在Mac OS X上的可可框架上找到密切相关的动态GUI库和OOP语言的示例,该框架用Objective-C编写,这是基于SmallTalk的Cobevice-C,是面向对象的,面向对象的,动态的消息扩展。 OOP工具包还增强了事件驱动的编程的普及(尽管此概念不限于OOP)。
在苏黎世EthZürich , Niklaus Wirth及其同事们还一直在研究诸如数据抽象和模块化编程之类的主题(尽管自1960年代或更早的时候,这一直很常用,但Wirth在模块边界上增加了类型检查)。 Modula-2 (1978)兼而有之的Oberon都包括一种独特的方法,用于对象取向,类等。继承在Wirth的设计中并不明显,因为他的命名法看起来相反:它称为类型扩展,观点是从父母到继承者的观点。
以对象为导向的功能已添加到许多以前现有的语言中,包括ADA , Basic , Fortran , Pascal和Cobol 。将这些功能添加到最初不是为其设计的语言中,通常会导致兼容性和可维护性的问题。
最近,出现了许多主要面向对象的语言,但也与程序方法兼容。两种此类语言是Python和Ruby 。可能是最重要的最近面向对象的语言是由Sun Microsystems开发的Java ,以及C#和Visual Basic.NET (VB.NET),均为Microsoft的.NET平台设计。这两个框架中的每一个都以自己的方式显示了通过创建实现的抽象来使用OOP的好处。 VB.NET和C#支持跨语言的继承,允许以一种语言定义的类来以另一种语言定义的类别类。
特征
面向对象的编程使用对象,但并非所有关联的技术和结构都直接支持声称支持OOP的语言。它在操作数上执行操作。下面列出的功能在被认为是强烈的类和对象的语言中很常见(或具有OOP支持的多范式),但有明显的例外。
- 可以存储以少数内置数据类型(例如整数和字母数字字符)中格式化的信息的变量。这可能包括数据结构,例如字符串,列表和哈希表,它们是内置的,或者是由使用内存指针组合变量而产生的。
- 程序 - 也称为功能,方法,例程或子例程- 采用输入,生成输出和操纵数据的过程。现代语言包括循环和有条件的结构化编程结构。
模块化编程支持可以为组织目的分组程序和模块。模块是命名的,因此一个模块中的标识符不会与另一个文件或模块中共享同名的过程或变量相冲突。
对象和类
支持面向对象的编程(OOP)的语言通常使用继承来重复使用和以类或原型的形式扩展性。那些使用类的人支持两个主要概念:
物体有时与现实世界中发现的事物相对应。例如,图形程序可能具有“圆”,“正方形”,“菜单”之类的对象。在线购物系统可能具有“购物车”,“客户”和“产品”之类的对象。有时对象表示更抽象的实体,例如代表打开文件的对象,或提供从美国习惯为公制转换测量的对象。
每个对像都被认为是特定类的实例(例如,将其名称字段设置为“玛丽”的对象可能是班级员工的一个实例)。面向对象的编程中的过程称为方法。变量也称为字段,成员,属性或属性。这导致以下术语:
- 类变量-整体属于班级;每个变量只有一个副本,在类的所有实例中共享
- 实例变量或属性 - 属於单个对象的数据;每个对像都有每个对象的副本
- 成员变量- 指由特定类定义的类和实例变量
- 类方法 -整体属于类,只能从过程调用中访问类变量和输入
- 实例方法 - 属于单个对象,并可以访问其调用特定对象的实例变量,输入和类变量
对象的访问有点像具有复杂内部结构的变量,并且在许多语言中,有效地指针,用作对堆或堆栈中内存中所述对象的一个实例的实际参考。它们提供了一层抽象,可用于将内部与外部代码分开。外部代码可以通过调用具有特定的输入参数集,读取实例变量或写入实例变量的特定实例方法来使用对象。对像是通过在类似于构造函数的类中调用特殊类型的方法来创建对象。程序可能会创建与运行同一类的许多实例,该实例独立运行。这是将相同过程用于不同数据集的简便方法。
使用类的面向对象的编程有时称为基于类的编程,而基于原型的编程通常不使用类。结果,使用显著不同但类似的术语来定义对象和实例的概念。
在某些语言中,可以使用其他概念(例如特质和混合物)组成类和对象。
基于班级的原型
在基于类的语言中,这些类是事先定义的,并且基于类实例化对象。如果从类果实实例化了两个苹果和橙色的物体,则它们本质上是水果,并且可以保证您可以以相同的方式处理它们。例如,程序员可以期望存在相同的属性,例如color或sugar_content或is_ -ripe 。
在基于原型的语言中,对象是主要实体。甚至都不存在。对象的原型只是将对象链接到的另一个对象。每个对像都有一个原型链接(只有一个)。可以基于选择作为其原型的已经存在的对象创建新对象。如果存在物体的水果,则可以将两个不同的物体称为苹果和橙色的水果,苹果和橙色都具有原型。水果类别的想法不是明确存在的,而是作为共享相同原型的对像类别的等效类别。原型的属性和方法委派给了该原型定义的等价类的所有对象。对象单独拥有的属性和方法可能不会由同一等价类的其他对象共享;例如,属性sugar_content可能意外地不存在苹果中的属性。只能通过原型实现单个继承。
动态调度/消息传递
对象的责任,而不是任何外部代码,选择以响应方法调用执行的程序代码,通常是通过在与对象关联的表中查找运行时间来查找该方法。此功能称为动态调度。如果呼叫的可变性比所谓的对象的单一类型更依赖(即方法选择中涉及至少一个其他参数对象),则说明多个调度。
方法调用也称为消息传递。它被概念化为消息(方法及其输入参数的名称)被传递给对象进行调度。
数据抽象
数据抽像是一种设计模式,其中数据仅在语义相关的功能中可见,以防止滥用。数据抽象的成功导致在面向对象和纯粹的功能编程中,经常将数据隐藏作为设计原理。
如果类不允许呼叫代码访问内部对像数据并仅允许通过方法访问,则这是一种被称为抽象的信息隐藏的形式。某些语言(例如,Java)让类明确地执行访问限制,例如使用private
关键字表示内部数据,并指定旨在用public
关键字在类外的代码使用的方法。方法还可以设计公共,私人或中间级别,例如protected
(这允许从同一类及其子类访问,但不能从其他类的对象访问)。在其他语言(例如Python)中,这仅是由约定执行的(例如, private
方法可能以下划线开头的名称)。在C#,Swift&Kotlin语言中, internal
关键字允许仅访问与同一组件,软件包或模块中的文件。
在编程语言,尤其是面向对象的语言中,对抽象的强调至关重要。面向对象的语言扩展了类型的概念以结合数据抽象,突出了通过方法限制访问内部数据的重要性。
封装
封装阻止外部代码关注对象的内部工作。这有助于代码重构,例如允许班级的作者更改该类的对像在内部表示其数据的方式而无需更改任何外部代码(只要“公共”方法调用以相同的方式工作)。它还鼓励程序员将所有与同一类中的一组数据集有关的代码,该代码可组织其他程序员的理解。封装是一种鼓励脱钩的技术。
组成,继承和委派
对象可以在其实例变量中包含其他对象;这被称为对象组成。例如,除了其自己的实例变量之外,员工类中的对象可能包含(直接或通过指针)在地址类中的对象。对象组成用于表示“ has-a”关系:每个员工都有一个地址,因此每个员工对像都可以访问一个存储地址对象的地方(要幺直接嵌入在自身内部,要幺在通过指针地址的单独位置中) 。
支持课程的语言几乎总是支持继承。这允许在代表“ IS-A型”关系的层次结构中安排类。例如,班级员工可能会从班级人那里继承。父级可用的所有数据和方法也出现在带有相同名称的子类中。例如,班级人员可能会定义变量“ first_name”和“ last_name” with方法“ make_full_name()”。这些也将在班级员工中提供,这可能会增加变量“职位”和“薪金”。除了可能以直观的方式反映现实世界的关系外,该技术允许轻松地重复使用相同的过程和数据定义。开发人员没有使用数据库表和编程子例程,而是利用用户可能更熟悉的对象:来自其应用程序域中的对象。
子类可以覆盖超类定义的方法。在某些语言中允许多种继承,尽管这可能会使解决方案变得复杂。某些语言对Mixins有特殊的支持,尽管在任何具有多种继承的语言中,Mixin只是一个不代表IS-A型关系的类。 Mixin通常用于在多个类中添加相同的方法。例如,类UnicodeConversionMixin可能会提供一种方法Unicode_to_ascii(),当包含在类fileReader和类WebPages Craper中时,它们不共享共同的父母。
抽像类不能被实例化为对象。它们仅出于可以实例化的其他“具体”类的继承而存在。在Java中, final
关键字可用于防止课程分类。
关于继承倡导者的组成学说,使用构图而不是继承实施has-a关系。例如,班级员工可以使每个员工对象成为内部人员对象,而不是从班级人员那里继承,即使班级人员有许多公共属性或方法,它也有机会隐藏外部代码。某些语言,例如GO,根本不支持继承。
“开放/封闭的原则”提倡班级和功能“应开放,以进行扩展,但要进行修改”。
委托是另一个可以用作继承的替代方案的语言功能。
多态性
亚型(一种多态性的一种形式)是,呼叫代码可以独立于其正在运行的受支持的层次结构中的哪个类 - 父级或其后代之一。同时,继承层次结构中对象之间的相同操作名称的行为可能有所不同。
例如,类型圆和平方的对像源自称为Shape的普通类。每种类型的形状的绘制功能实现了绘制自身所必需的东西,而调用代码可能对要绘制的特定类型的形状漠不关心。
这是另一种简化类层次结构外部代码的抽像类型,并实现了大量关注的分离。
开放递归
在支持打开递归的语言中,对象方法可以在同一对象(包括自己)上调用其他方法,通常使用称为this
或self
的特殊变量或关键字。这个变量是较晚的。它允许在一个类中定义的一种方法来调用以后在某些子类中定义的另一种方法。
OOP语言
Simula (1967)通常被认为是具有对象语言的主要特征的第一语言。它是为制作模拟程序而创建的,其中所谓的对像是最重要的信息表示。 Smalltalk (1972至1980年)是另一个早期的例子,并且开发了大部分OOP理论。关于对象取向的程度,可以进行以下区别:
- 语言称为“纯” OO语言,因为其中的所有内容都被视为对象,来自字符和标点符号,一直到整个班级,原型,块,模块等。甚至强制执行,OO方法。示例:红宝石, Scala , Smalltalk , Eiffel , Emerald , Jade , Self , Raku 。
- 语言主要用于OO编程,但具有一些程序元素。示例: Java , Python , C ++ , C# , Delphi / Object Pascal , vb.net 。
- 历史上是程序性语言,但已使用一些OO功能扩展。示例: PHP , JavaScript , Perl , Visual Basic (源自基本), MATLAB , COBOL 2002 , FORTRAN 2003 , ABAP , ADA 95 , PASCAL 。
- 具有对象的大多数特征(类,方法,继承)的语言,但具有明显的原始形式。示例: Oberon (Oberon-1或Oberon-2)。
- 具有抽像数据类型支持的语言,可用于类似于OO编程,但没有对象取向的所有功能。这包括基于对象的和基于原型的语言。示例: JavaScript , Lua , Modula-2 , Clu 。
- 变色龙语言支持多种范式,包括OO。 TCL在TCLOO中脱颖而出,TCLOO是一种支持基于原型的编程和基于类的OO的混合对象系统。
动态语言中的oop
近年来,以对象为导向的编程在动态编程语言中尤其流行。 Python , Powershell , Ruby和Groovy是基于OOP原理的动态语言,而Perl和PHP自Perl 5和PHP 4以来一直在添加面向对象的功能,以及自版本6以来的ColdFusion 。
Internet上HTML , XHTML和XML文档的文档对像模型具有对流行的JavaScript / Ecmascript语言的绑定。 JavaScript也许是最著名的基于原型的编程语言,它采用了从原型的克隆而不是从类中继承(与基于类的编程形成对比)。采用这种方法的另一种脚本语言是LUA 。
网络协议中的oop
计算机之间流动以在客户端服务器环境中请求服务的消息可以设计为由客户端和服务器已知的类对象定义的对象的线性化。例如,一个简单的线性化对象将由一个长度字段,标识类的代码点和数据值组成。一个更复杂的示例将是一个命令,由命令的长度和代码点组成,由代表命令参数的线性化对象组成。每个这样的命令必须由服务器指向其类(或超类)识别命令并能够提供请求的服务的对象。客户和服务器最好将其建模为复杂的面向对象的结构。分布式数据管理体系结构(DDM)采用了这种方法,并使用类对像在四个正式层次结构的四个层面上定义对象:
- 定义形成消息的数据值的字段,例如其长度,代码点和数据值。
- 对象和对象的集合类似于SmallTalk程序中的消息和参数。
- 经理类似于IBM I对象,例如由元数据和记录组成的文件和文件的目录。经理在概念上为其包含的对象提供内存和处理资源。
- 由实施完整处理环境所需的所有经理组成的客户或服务器,支持目录服务,安全性和并发控制等方面。
DDM定义的分布式文件服务的初始版本。后来扩展为分布式关系数据库体系结构(DRDA)的基础。
设计模式
通过几种方法解决了面向对象设计的挑战。最常见的是Gamma等人编码的设计模式。 。更广泛地说,“设计模式”一词可用于将任何一般,可重复的解决方案模式指向软件设计中常见的问题。这些通常发生的问题中的一些具有针对对象发展的含义和解决方案。
继承和行为亚型
直观地假设继承创建语义是“一种关系”,因此推断从子类实例化的对象可以始终安全地使用,而不是从超级类实例化的对象。不幸的是,在大多数OOP语言中,这种直觉是错误的,尤其是在所有允许可变对象的语言中。类型Checker用OOP语言(带有可变对象)强制执行的亚型多态性不能保证在任何情况下行为亚型。行为亚型通常是不确定的,因此无法通过程序(编译器)实施。考虑到无法句法检测的可能的错误用途,必须仔细设计类或对象层次结构。这个问题被称为Liskov替代原则。
团伙四种设计模式
设计模式:可重复使用的面向对象的软件的元素是一本有影响力的书,由Erich Gamma , Richard Helm , Ralph Johnson和John Vlissides于1994年出版,通常被幽默地称为“四个人的帮派”。除了探索面向对象的编程的功能和陷阱外,它还描述了23个常见的编程问题和解决方案的模式。
该书描述了以下模式:
- 创建模式(5):工厂方法模式,抽象的工厂模式,单例模式,建筑商模式,原型图案
- 结构图案(7):适配器图案,桥梁图案,复合图案,装饰器图案,外观图案,轻巧图案,代理图案
- 行为模式(11):责任链模式,命令模式,解释器模式,迭代器模式,调解器模式,纪念品模式,观察者模式,状态模式,策略模式,模板方法模式,访客模式
对象方向和数据库
当今的软件中,面向对象的编程和关系数据库管理系统(RDBMS)非常普遍。由于关系数据库不会直接存储对象(尽管有些RDBMS具有面向对象的功能以近似此近似),因此通常需要桥接两个世界。与关系数据库桥接面向对象的编程访问和数据模式的问题被称为对象相关阻抗不匹配。有多种应对此问题的方法,但是没有弊端的一般解决方案。最常见的方法之一是对象相关的映射,如IDE语言(例如Visual FoxPro)以及Java数据对象和Ruby等库ActivereCord中所示。
还有一些可以用于替换RDBMS的对像数据库,但是这些在技术和商业上并不像RDBMS那样成功。
现实世界建模和关系
OOP可用于将现实世界对象和过程与数字对应物相关联。但是,并非所有人都同意OOP促进了直接的现实映射(请参阅批评部分),或者现实世界中的映射甚至是一个值得的目标。贝特兰·迈耶(Bertrand Meyer)在面向对象的软件构建中指出,程序不是世界的模型,而是世界某些地区的模型。 “现实是堂兄两次删除”。同时,已经注意到了OOP的一些主要局限性。例如,使用OOP的继承概念很难解决圆圈问题。
但是,尼克劳斯·沃思(Niklaus Wirth)(他普及了现在被称为沃思定律的格言:“软件变得比硬件速度慢得多”)在他的论文中谈到了OOP,“通过看着玻璃的好主意”,“这个范式”紧密反映了这个范式系统“现实世界中”的结构,因此非常适合模拟具有复杂行为的复杂系统”(对比吻原理)。
史蒂夫·耶格(Steve Yegge )和其他人指出,自然语言在操作(方法/动词)之前缺乏严格优先考虑事物(对象/名词)的OOP方法。与程序编程相比,此问题可能导致OOP遭受更复杂的解决方案。
OOP和控制流
开发了OOP来增加源代码的可重复性和可维护性。对照流的透明表示没有优先级,并且应由编译器处理。随着并行硬件和多线程编码的越来越多的相关性,开发透明的控制流变得越来越重要,而OOP很难实现。
责任 - 与数据驱动的设计
责任驱动的设计根据合同定义了类,也就是说,应围绕责任及其共享的信息定义类。 Wirfs-Brock和Wilkerson与数据驱动的设计形成了鲜明对比,在该设计中,围绕必须持有的数据结构定义了类。作者认为,由责任驱动的设计是可取的。
固体和掌握指南
Solid是由Michael Feathers发明的助记符,它阐明了五个软件工程设计原则:
Grasp (一般责任分配软件模式)是Craig Larman提倡的另一套准则。
批评
OOP范式因多种原因而受到批评,包括不符合其可重复性和模块化的既定目标,以及过度强调软件设计和建模(数据/对象)的一个方面,以其他重要方面(计算/算法)为代价。
卢卡·卡德利(Luca Cardelli)声称,与程序代码相比,OOP代码“本质上的效率更低”,OOP可能需要更长的编译,并且OOP语言“相对于班级扩展和修改,模块化属性极差,并且往往是极其复杂的。埃尔兰的主要发明者乔·阿姆斯特朗(Joe Armstrong)重申了后一点,他引用了:
面向对象的语言的问题在于他们拥有随身携带的所有隐性环境。您想要一个香蕉,但您得到的是一颗拿着香蕉和整个丛林的大猩猩。
Potok等人的研究。 OOP和程序方法之间的生产率没有显著差异。
Christopher J. Date指出,由于缺乏对OOP的约定和严格的定义,因此很难将OOP与其他技术进行批判性比较,特别是关系。但是,Date和Darwen在OOP上提出了一个理论基础,该基础使用OOP作为一种可自定义类型的系统来支持RDBMS 。
劳伦斯·克鲁伯纳(Lawrence Krubner)在一篇文章中声称,与其他语言(LISP方言,功能性语言等)相比,OOP语言没有独特的优势,并且造成了不需要的复杂性的沉重负担。
亚历山大·史蒂芬诺夫(Alexander Stepanov)将对象取向不利地比较通用编程:
我发现从技术上讲OOP。它试图以一种类型的界面来分解世界。为了解决真正的问题,您需要多个代数 - 跨越多种类型的接口家族。我发现OOP从哲学上不健全。它声称一切都是对象。即使是真的,也不是很有趣 - 说一切都是一个对像根本没有说什么。
保罗·格雷厄姆(Paul Graham)建议,OOP在大公司中的受欢迎程度是由于“大型(且经常变化的)平庸的程序员”。根据格雷厄姆(Graham)的说法,OOP施加的纪律阻止了任何一个程序员“造成太多损害”。
狮子座布罗迪(Leo Brodie)提出了对象的独立性质与违反不重复自己软件开发原则复制代码的趋势之间的联系。
史蒂夫·耶格(Steve Yegge)指出,与功能编程相反:
面向对象的编程将名词放在首位。您为什么要竭尽全力将演讲的一部分放在基座上?为什么一种概念应该优先于另一个概念?好像OOP突然使动词在我们实际思考的方式上变得不那么重要。这是一个奇怪的偏见的观点。
Clojure的创建者Rich Hickey将对象系统描述为现实世界中过于简单的模型。他强调了OOP无法正确建模时间,随着软件系统变得更加同时发生,这越来越有问题。
UNIX程序员和开源软件倡导者Eric S. Raymond对以对象为导向的编程作为“一个真正的解决方案”的主张批评,并写了以对象为导向的编程语言,倾向于鼓励大分层的程序,破坏透明度。雷蒙德(Raymond)将其与UNIX和C编程语言采取的方法进行了比较。
参与UTF-8和GO的程序员Rob Pike称其为面向对象的编程为“计算的罗马数字”,并表示OOP语言经常将焦点从数据结构和算法转移到类型上。此外,他引用了Java教授的一个实例,该教授的“惯用性”解决方案是创建六个新类,而不是简单地使用查找表。
关于继承,鲍勃·马丁(Bob Martin)指出,由于它们是软件,因此相关类并不一定会分享其代表的事物的关系。
正式语义
对像是面向对象的系统中的运行时实体。他们可以代表一个人,一个地方,银行帐户,数据表或该程序必须处理的任何项目。
已经有多次尝试将面向对象的编程中使用的概念形式化。以下概念和结构已被用作OOP概念的解释:
- CO代数数据类型
- 递归类型
- 封装状态
- 遗产
- 记录是理解对象的基础,如果函数文字可以存储在字段中(例如在功能编程语言中),但是实际的微积分需要更为复杂才能结合OOP的基本特征。已经研究了系统f <:的几个扩展。这些允许亚型多态性和参数多态性(仿制药)
试图在对象背后找到共识的定义或理论并未证明非常成功(但是,请参见Abadi&Cardelli,这是许多OOP概念和构造的形式定义的对象理论),并且通常会广泛分歧。例如,某些定义着眼于心理活动,而有些定义则关注程序结构。更简单的定义之一是,OOP是使用“映射”数据结构或阵列的行为,该行为可以包含函数和指针到其他地图,所有这些都在顶部带有一些句法和范围的糖。可以通过克隆地图(有时称为“原型”)来执行继承。
也可以看看
- 编程语言的比较(面向对象的编程)
- 编程范例的比较
- 基于组件的软件工程
- 通过合同设计
- 对象关联
- 对像数据库
- 对像模型参考
- 对象建模语言
- 面向对象的分析和设计
- 面向对象的本体论
- 对象相关阻抗不匹配(和第三张宣言)
- 对象相关映射
系统
- 赛车
- 通用对象请求经纪架构(CORBA)
- 分布式组件对像模型
- 分布式数据管理体系结构
- 杰鲁