近年来,像Perl和C#这样的主流语言采用匿名方法/函数是否重要,还是一种违反面向对象原则的怪异特性?
类似Intel最新版本的Thread Building Blocks和Microsoft的PPL和Linq等最新库是否依赖于此类功能是好事,还是不好?
Java等当前拒绝使用匿名方法/函数的语言是否明智地坚持纯面向对象模型,还是因缺乏基本编程功能而落后?
近年来,像Perl和C#这样的主流语言采用匿名方法/函数是否重要,还是一种违反面向对象原则的怪异特性?
类似Intel最新版本的Thread Building Blocks和Microsoft的PPL和Linq等最新库是否依赖于此类功能是好事,还是不好?
Java等当前拒绝使用匿名方法/函数的语言是否明智地坚持纯面向对象模型,还是因缺乏基本编程功能而落后?
lambda表达式的表现力结合像LINQ这样流畅的API,远远超过了纯面向对象原则所认为的任何违规行为。
面向对象编程是一种设计哲学,而不是刻在石板上的命令集。
由于Lambda函数大大增强了语言的功能和表达能力,仅仅因为“违反纯OO模型”而拒绝使用它们是相当自我毁灭的:总体目标是设计良好的软件,而不是设计面向对象的代码。
此外,我并不确定正确编写的Lambda函数本质上是否“违反了OO模型”。更像是超越了模型所限制的范围。
我并没有看到任何违反面向对象原则的地方,无论是封装、继承还是多态性都不与AM矛盾。它们只是一种方法,而不是一种类型。就像完整的 .Net 1.1 方法委托表示一样,它们可以被编写成使用或滥用三种面向对象原则中的任何一种。
C#一直拥有委托和事件处理。CLR 2.0(以及C# 2.0)引入了匿名委托的概念,以满足各种需要,这些需要在任何面向对象技术中都可以通过设计模式来解决。它们正式宣布函数是这些技术中的“一等公民”。
我敢说,在像C#这样的技术中混合功能和对象特性变得如此有用,以至于很难想象没有同时享受两个世界的好处的应用程序。
Java并非出于原则而坚持纯面向对象模型;Java社区只是无法就语言的功能性添加达成一致,或者说不确定这些添加是否值得在语法上增加额外的复杂性。根据James Gosling的说法:
最初Java没有闭包主要是因为时间压力,而不是其他原因。在Java早期,缺乏闭包是相当痛苦的,因此内部类应运而生:这是一种不舒适的妥协,试图避免许多困难问题。但正如在许多设计问题中通常发生的那样,简化并没有真正解决任何问题,它们只是将问题转移了。
(摘自“理解闭包辩论”,这是去年夏天Java社区中关于函数式编程辩论状态的相当好的概述。共识似乎是现在暂时搁置这个问题。)
Python一直都有它们。
函数是一类具有非常狭窄接口和不多属性的对象。
Python函数对象具有许多内置属性,如果需要,您总是可以添加更多属性。
回调函数是面向对象编程的基本组成部分。对于单方法回调对象的常见情况,有好的语法支持是非常有意义的。具体实现方式则另当别论。
它如何违反OO原则?
它不会违反封装:类仍然完全控制哪些函数可以访问其私有成员。
它也不会干扰继承或多态性。
只有当你是Java程序员并将“OO原则”定义为“可以在Java中实现”时,它才违反OO原则。
幸运的是,在Java之外的世界中,从未使用过这样的OOP定义。
它可能被认为违反了Java的哲学,我会说这是件好事,因为Java的哲学本质上是“从一个破碎和混乱的OOP版本开始,并保持不变,从未以任何有意义的方式添加或发展它”。这不是一种值得保持不变的哲学。
但它并不违反面向对象编程的原则。