匿名方法/函数:是一项基本功能还是违反面向对象原则的行为?

3

近年来,像Perl和C#这样的主流语言采用匿名方法/函数是否重要,还是一种违反面向对象原则的怪异特性?

类似Intel最新版本的Thread Building Blocks和Microsoft的PPL和Linq等最新库是否依赖于此类功能是好事,还是不好?

Java等当前拒绝使用匿名方法/函数的语言是否明智地坚持纯面向对象模型,还是因缺乏基本编程功能而落后?


4
Java有匿名类,可以拥有方法。它们在一段时间前加入了匿名类的行列。 - amischiefr
1
可惜 Java 语法如此冗长。 - Tom Hawtin - tackline
谁会在意“OO原则的违规”?你提到的两种语言都没有支持真正的OOP。至少在C#和C++中,你可以选择其他范式来代替它。 - jalf
1
Smalltalk,大多数面向对象语言的鼻祖,也具有lambda表达式,因此这不是一个新概念。只是像C++/C#/Java这样的语言正在赶上几十年前所做的研究。 - Martin York
8个回答

18

lambda表达式的表现力结合像LINQ这样流畅的API,远远超过了纯面向对象原则所认为的任何违规行为。


说得好。如果你花足够的时间去学习,它就会变得自然而然,并且融入到面向对象的结构中。 - Dykam
我同意。我的兴趣更多地在于理解相反的观点。为什么有些语言会拒绝这样的东西?(对于像C这样的低级语言,这是显而易见的,但其他语言呢?) - RD1
@Rowan,除了坚持原则之外,另一个不实现它的原因是它很难 :)。我在VB.Net实现lambda表达式的基础上进行了大量工作。你会很惊讶于在语言设计上花费了多少时间来实现这个特定的功能,而不是实际编码。 - JaredPar

13

面向对象编程是一种设计哲学,而不是刻在石板上的命令集。

由于Lambda函数大大增强了语言的功能和表达能力,仅仅因为“违反纯OO模型”而拒绝使用它们是相当自我毁灭的:总体目标是设计良好的软件,而不是设计面向对象的代码。

此外,我并不确定正确编写的Lambda函数本质上是否“违反了OO模型”。更像是超越了模型所限制的范围。


+1,尽管如果它某种方式违反了面向对象的原则,我会有兴趣思考一下如何调整我的设计来适应它。 - Jeff Sternal

3

我并没有看到任何违反面向对象原则的地方,无论是封装、继承还是多态性都不与AM矛盾。它们只是一种方法,而不是一种类型。就像完整的 .Net 1.1 方法委托表示一样,它们可以被编写成使用或滥用三种面向对象原则中的任何一种。


1

C#一直拥有委托和事件处理。CLR 2.0(以及C# 2.0)引入了匿名委托的概念,以满足各种需要,这些需要在任何面向对象技术中都可以通过设计模式来解决。它们正式宣布函数是这些技术中的“一等公民”。

我敢说,在像C#这样的技术中混合功能和对象特性变得如此有用,以至于很难想象没有同时享受两个世界的好处的应用程序。


1

Java并非出于原则而坚持纯面向对象模型;Java社区只是无法就语言的功能性添加达成一致,或者说不确定这些添加是否值得在语法上增加额外的复杂性。根据James Gosling的说法:

最初Java没有闭包主要是因为时间压力,而不是其他原因。在Java早期,缺乏闭包是相当痛苦的,因此内部类应运而生:这是一种不舒适的妥协,试图避免许多困难问题。但正如在许多设计问题中通常发生的那样,简化并没有真正解决任何问题,它们只是将问题转移了。

(摘自“理解闭包辩论”,这是去年夏天Java社区中关于函数式编程辩论状态的相当好的概述。共识似乎是现在暂时搁置这个问题。)


这真是太遗憾了,因为有一些函数式构造(一级匿名函数)可以将一页代码转化为几行代码,这些代码易于理解(例如,在列表上进行map/fold操作)。 - RHSeeger

0

Python一直都有它们。

函数是一类具有非常狭窄接口和不多属性的对象。

Python函数对象具有许多内置属性,如果需要,您总是可以添加更多属性。


0

回调函数是面向对象编程的基本组成部分。对于单方法回调对象的常见情况,有好的语法支持是非常有意义的。具体实现方式则另当别论。


0

它如何违反OO原则?

它不会违反封装:类仍然完全控制哪些函数可以访问其私有成员。

它也不会干扰继承或多态性。

只有当你是Java程序员并将“OO原则”定义为“可以在Java中实现”时,它才违反OO原则。

幸运的是,在Java之外的世界中,从未使用过这样的OOP定义。

它可能被认为违反了Java的哲学,我会说这是件好事,因为Java的哲学本质上是“从一个破碎和混乱的OOP版本开始,并保持不变,从未以任何有意义的方式添加或发展它”。这不是一种值得保持不变的哲学。

但它并不违反面向对象编程的原则。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接