2010-07-30 56 views
8

封閉反對階級有什麼利弊?反之亦然?正如用戶Faisal所說的,閉包和類都可以用來「描述維護和操作狀態的實體」,所以閉包提供了一種使用函數式語言以面向對象的方式進行編程的方法。像大多數程序員一樣,我對類更加熟悉。關閉和傳統課程有什麼區別?

這個問題的目的不是要開啓另一場有關最佳編程範式的火焰戰爭,或者封閉和類是完全相同的,或者是窮人的另一個。

我想知道的是,如果任何人發現一個方案真的擊敗另一個方案,爲什麼。

+1

以與語言無關的方式回答這個問題非常非常困難,因爲最方便的答案几乎必然取決於您使用的語言。 – zneak 2010-07-30 05:20:02

回答

9

從功能上來說,閉包和對象是等價的。閉包可以模擬一個對象,反之亦然。所以你使用哪一個是語法方便的問題,或者你的編程語言最能處理哪一個問題。

在C++中,閉包不是語法上可用的,因此您不得不使用「函子」,它們是覆蓋operator()的對象,並且可能以看起來像函數調用的方式調用。

在Java中,你甚至不用函子,所以你得到的東西,如Visitor模式,它也只是在支持閉包語言高階函數。

在標準的方案你沒有對象,所以有時你最終通過寫截流用調度功能,執行根據傳入的參數不同的子倒閉實現它們。

在像Python語言,它的語法既有仿函數和關閉,這是基本的味道和你覺得是更好的方式來表達自己在做什麼的問題。

就個人而言,我要說的是,在具有語法雙方任何語言,閉包是一個更加清晰乾淨的方式來表達同一個方法的對象。反之亦然,如果你的閉包基於傳入的參數開始處理分派到子閉包,你應該使用一個對象來代替。

2

閉包與類非常相關。類允許你定義字段和方法,閉包保存來自函數調用的局部變量的信息。用語言無關的方式不可能比較兩者:它們根本沒有達到相同的目的。此外,閉包與函數式編程相比更多地涉及面向對象編程。

例如,看看下面的C#代碼:

static void Main(String[] args) 
{ 
    int i = 4; 
    var myDelegate = delegate() 
    { 
     i = 5; 
    } 

    Console.WriteLine(i); 
    myDelegate(); 
    Console.WriteLine(i); 
} 

這給出了 「4」,然後 「5」。 myDelegate作爲一個委託,是一個閉包,並且知道函數當前使用的所有變量。因此,當我打電話時,可以在內改變i的「父」功能的值。這對於正常功能是不允許的。

類,如果你知道它們是什麼,是完全不同的。

您的困惑的一個可能原因是,當語言沒有語言支持閉包時,可以使用類來模擬它們,這些類將包含我們需要保留的每個變量。例如,我們可以把上面的代碼是這樣的:

class MainClosure() 
{ 
    public int i; 

    void Apply() 
    { 
     i = 5; 
    } 
} 

static void Main(String[] args) 
{ 
    MainClosure closure; 
    closure.i = 4; 

    Console.WriteLine(closure.i); 
    closure.Apply(); 
    Console.WriteLine(closure.i); 
} 

我們已經改變了delegate的,我們打過電話MainClosure類。我們沒有在Main函數中創建變量i,而是創建了MainClosure對象,該對象具有i字段。這是我們將要使用的。另外,我們已經構建了函數在實例方法內執行的代碼,而不是在方法內部執行。如你所見,儘管這只是一個簡單的例子(只有一個變量),但它的工作量相當大。在需要關閉的環境中,使用對象是一個糟糕的解決方案。然而,課程不僅對創建閉包有用,而且它們的通常目的通常差異很大。

+1

我也這麼認爲,但是關於閉包或對象是否更具表現力,顯然存在很多爭議。讓我給你一些討論的味道:http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html – Faisal 2010-07-30 04:51:06

+0

根據我的理解,你可以通過閉包來實現對象,並且您可以通過對象模擬閉合點。但是,對象通常不會自動捕獲本地環境,因此您必須明確地初始化它們......但@zneak是正確的:它們最終服務於兩個不同的目的,並且兩者都不是不合理的。 – Amadan 2010-07-30 04:56:43

+0

@Faisal:我相信這個辯論是關於明確地使用閉包與創建類來模擬閉包的情況,在這種情況下,「全功能」閉包明顯更方便。 – zneak 2010-07-30 04:57:22

4

就我個人而言,我認爲這是一個使用正確工具來完成工作的問題......更具體地說,就是正確傳達您的意圖。

如果你想明確地表明,所有的對象都有一個共同的定義,並希望這樣的強類型檢查,你可能想使用一個類。在這種情況下,無法在運行時更改類的結構的缺點實際上是一種優勢,因爲您確切知道自己正在處理的是什麼。

相反,如果你想創建「對象」的異類集合(即狀態變量表示在某些功能瓦特/內部函數來處理這些數據關閉),你可能會更好創建一個封閉。在這種情況下,對於最終對象的結構沒有真正的保證,但是您可以在運行時按照自己的喜好靈活地定義它。

謝謝你問,其實;我回應了一個膝蓋上的反應:「課程和封閉是完全不同的!」態度,但是通過一些研究,我發現問題並不像我想象的那樣枯燥無味。

+0

換句話說,在大多數OOP語言中,閉包作爲對象更像*接口* - 內部表示是完全隱藏的,任何提供相同公共方法的東西都可以交換。有些人實際上認爲這是更好的OOP風格,有趣... – 2010-07-30 14:08:45