F#入門-第四章 面向對象-第一節 對象

■ 對象
    F#的面向對象是與.NetFramework的面向對象有着緊密聯繫的。也就是說,F#具備了與C#等.NetFramework中的語言中面向對象所相同的面向對象機制。因此,F#中支持了OCaml中所不支持的重載(overload)功能,但是另一方面,作爲其結果,OCaml中所具有的類型推理的完全性在F#中就不具備了。另外,關於類的描述方法也與Ocaml不同,所以論及面向對象這一部分,F#是與Ocaml互不兼容的,最好理解成兩種不同的語言比較好。(關於重載在後文詳述)。

類型推理的完全性
類型推理的完全性是指
如果加上類型註釋就能進行類型推理的話,那麼沒有類型註釋也可以進行類型推理的這種性質。
這是OCaml中類型系統的優點之一。


    那麼,讓我們來開始針對面向對象進行思考。
    首先,如果可以針對面向對象作個精確定義就好了,但是面向對象並不是這麼簡單的。

    因爲,構成面向對象這種想法的起源並不是單一的一門語言,是由多個語言共同構成的,而各個語言中關於面向對象的想法又各有區別。

    例如,大多數面向對象的語言中,類是一種模式,實現類並創建對象叫做實例化。

    因此,將對象與類分開來考慮的語言有很多,但是在面向對象的起源之一的Smalltalk等語言中,類本身就是對象,綜合起來,就很難對面向對象進行定義了。

    首先,關於類,它是將數據與函數進行集中彙總之後產生的。但是在各個語言中對於數據和函數的稱呼方法又各不相同。例如在Java中,將數據稱爲字段,函數稱爲方法,在C++中將數據稱爲成員變量,函數稱爲成員函數。本書結合Expert F#或Foundations F#的稱呼方法,在有必要作區分時,將數據稱爲字段,函數稱爲方法或成員函數,沒必要進行區分時統稱爲成員。

    類具有繼承的概念,繼承了某個類後的類也繼承了被繼承類中的所有成員。本書中將被繼承的類稱爲父類,繼承父類的類稱爲子類。

    接着讓我們進入正題。在.Net Framework中面向對象的代表性語言爲C#。一切都是object類的子類。也就是說,所有的類型都可上溯(Upercast)爲Object類型。F#中也有相當於這種Object類型的obj類型,所有的類型都可上溯爲obj類型。

上溯爲obj型
let a = 1 :> obj;;
val a : obj
> let b = "abc" :> obj;;
val b : obj


    :>是上溯時使用的運算符。上溯是指,將任何對象的類型轉變爲該對象父類的類型,反之將任何對象的類型轉變爲該對象子類的類型稱之爲下溯。上溯是安全的,因爲編譯器總是知道該對象的父類型,下溯是不安全的,因爲當前類型未必能夠轉化爲目標子類型。

    在F#中把各類型之間的轉變稱爲轉換。轉換成obj類型是把任意類型轉變成obj類型,與box函數作用相同。

box函數
> let a = box 1;;
val a : obj
> let b = box "abc";;
val b : obj


    同時,也具有unbox函數用來把obj類型的函數轉變成原有類型。但是,如果轉換不成功則會引發異常,請注意這一點。
 

unbox函數
> let a = box 1;;
val a : obj
> let b = unbox<int> a;;
val b : int
> let c = unbox<string> a;;
val c : string
System.InvalidCastException: 指定的轉換無效。
    位置 <StartupCode$FSI_0009>.$FSI_0009._main()
stopped due to error


    因此,下溯時通常使用類型測試運算符:?來判斷是否能實現轉換。

類型測試運算符的利用
let a = box 1 in
let b = box "abc" in
let check (x:obj) =
         match x with
         | :? int -> System.Console.WriteLine "int"
         | :? string -> System.Console.WriteLine "string"
         | _ -> System.Console.WriteLine "other type" in
check a;check b;;


    類型測試運算符可以當作函數那樣來利用。如果象( obj :? type )這樣來使用時,obj可以轉換爲type時返回true,否則返回false。

類型測試運算符的利用之2
> let a = box 1 in if (a :? int) then true else false;;
val it : bool = true
發佈了55 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章