F#入門-第四章 面向對象-第三節 成員函數

成員函數
  上一節我們學習了給類添加字段的方法,本節介紹如何讓類具有成員函數.如前所述,類所具有的函數叫做方法或成員函數。

    將定義成員函數的書寫方法提取如下

 成員函數的定義
     類定義 :=
     type 類名 [ 模式 ] [ as 識別符 ] =
      class
      ...
      [元素類型定義]*
     end
    元素類型定義 :=
      | 成員定義
      | ...
    成員定義 :=
      | [ static ] member 成員綁定
      | ...
    成員綁定 :=
      | [ 識別符 '.' ] 綁定
      | [ 識別符 '.' ] 識別符 with 綁定


    因爲光看以上描述是很難理解的,所以讓我們來看個例子,該例子定義三個成員函數與一個屬性。

成員函數的定義
open System;;
type ClassWithMember = class
    val mutable data : int
    new (init) = {data = init;}
    member x.show _ = Console.WriteLine(x.data)
    member x.addshow y = Console.WriteLine(x.data + y)
    member x.update input = x.data <- input
    member x.prop = 10
    end;;
let obj = new ClassWithMember(10) in
obj.show();
obj.addshow(10);
obj.update(100);
obj.show();
obj.addshow(10);
Console.Write(obj.prop);;


    member是聲明成員時用的關鍵字。在這之後,以“類本身的引用名.成員函數名模式1...=函數體”的形式定義了函數。將member關鍵字與類本身的引用名這一部分去除掉,就與普通函數定義沒什麼區別了。當然,成員函數也可以進行柯里化,可以用別的變量來代替,調用函數時,採用對象名.成員函數名的形式進行調用。

    使用類本身的引用名是爲了從函數體內部可以訪問自身類中進行定義的其他成員,通常類本身的引用名爲x或v等很短小的名字,或this,self這類名字。這個例子中使用了x爲類自身的引用名,可以通過x.data來引用x的成員data的值。另外,可以象prop成員那樣,定義不帶參數的成員。

靜態成員函數
   成員函數基本上是通過對象來進行調用的,但是如果加上static關鍵字,就可以通過類來進行調用了。因此,聲明靜態函數時,不需要加上類自身的引用名。

    象數學計算用類這樣的不需要具體對象的類經常調用靜態成員函數。在下例中,定義了一個非常簡單的Math類,該類具有一個返回數值絕對值的靜態成員函數。

靜態成員函數
type Math = class
    static member abs v = if v<0 then -v else v
    end;;
let a = Math.abs(-10) in
System.Console.WriteLine(a);;


    象這樣,採用類名.函數名的形式來調用靜態成員函數。

將記錄類型作爲對象使用
  在介紹記錄類型的時候並沒有對此進行介紹。記錄可以具有除字段之外的其他成員。因此,可以用記錄來模擬對象。

    採用如下所示方法給記錄定義成員函數。成員函數名前面的類型名相當於對類進行定義時類本身的引用名。

 具有成員函數的記錄的定義
    type 類型名 = { 字段名1 : 類型名1; ... ; 字段名n : 類型名n }
    with
    member 類型名1.成員函數名1 模式1 ... 模式n = 函數體
     ..
    member 類型名n.成員函數名n 模式1 ... 模式n = 函數體
    end


    通過這種方法,可以創建表示點座標的記錄.

Point類型的利用
type Point = {mutable x : int; mutable y : int}
    with
        member v.move (p:Point) =
            v.x <- v.x + p.x;
            v.y <- v.y + p.y;
        member v.show _=
            System.Console.WriteLine ("x=" ^ v.x.ToString() ^ ",y=" ^ v.y.ToString())
        end;;
let p = {x=10;y=10} in
let move_vector = {x=100;y=100} in
p.show();
p.move(move_vector);
p.show();;


    Point類型是隻帶有x與y的值的簡單數據類型,帶有顯示字段值的show方法與接受另一個Point類型的參數(作爲移動的向量)的方法move。

    正如這個例子所示,訪問成員函數與訪問字段一樣,都通過點符號來進行訪問。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章