日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

F#探险之旅(四):面向对象编程(中)

發(fā)布時間:2025/4/16 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 F#探险之旅(四):面向对象编程(中) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

F#系列隨筆索引

對象表達式(Object Expressions)

F#中的OOP語法很簡潔,而對象表達式則正是這種簡潔性的核心所在。通過對象表達式,我們可以創(chuàng)建抽象類或接口的輕量級實現(xiàn),也可以對一個具體的類進行繼承。換言之,可以在實現(xiàn)抽象類或接口,或者繼承具體類的同時創(chuàng)建新類型的一個實例。下面來看如何對泛型接口IComparer<’T>應用對象表達式。

F# Code
#light
open System
open System.Collections.Generic

let revStringComparer =
{
new IComparer<string>
with
Compare(s1, s2) =
let rev (s : string) =
new string(Array.rev(s.ToCharArray()))
let reversed = rev s1
reversed.CompareTo(rev s2)
}

let winners = [| "Sandie Shaw"; "Bucks Fizz"; "Dana International"; "Abba" |]

print_any winners
print_newline()
Array.Sort(winners, revStringComparer)
print_any winners


運行結果為

Output
[|"Sandie Shaw"; "Bucks Fizz"; "Dana International"; "Abba"|]
[|"Abba"; "Dana International"; "Sandie Shaw"; "Bucks Fizz"|]


這里演示了實現(xiàn)IComparer的過程,該接口有一個方法Compare,它接受兩個參數(shù)并通過返回值來表示參數(shù)比較的結果。它是泛型接口,這里的類型參數(shù)為string,可以在標識符revStringComparer定義的第二行看到。從標識符的名字也可以了解到,它是將參數(shù)顛倒后進行比較,運行結果的第二行印證了這一點。可以看到“在實現(xiàn)接口的同時返回一個實例”。

看看多重繼承的情況。在C#中,一個類不能繼承多個類,卻可以同時實現(xiàn)多個接口,F#也是一樣的。要注意的是,如果同時繼承類并實現(xiàn)接口,須將類的部分房子最前面;而且必須在第一個類/接口定義完畢之后才能開始第二個接口的實現(xiàn)。

多重繼承的例子
#light
open System
open System.Drawing
open System.Windows.Forms

let makeNumberControl(n: int) =
{
new Control(Tag = n, Width = 32, Height = 16)
with
override x.OnPaint(e) =
let font = new Font(FontFamily.Families.[1], 12.0F)
e.Graphics.DrawString(n.ToString(), font, Brushes.Black,
new PointF(0.0F, 0.0F))

interface IComparable
with
CompareTo(other) =
let otherCtrl = other :?> Control in
let n1 = otherCtrl.Tag :?> int in
n.CompareTo(n1) }

let numberCtrls =
let temp = new ResizeArray<Control>()
let random = new Random()
for index = 1 to 10 do
temp.Add(makeNumberControl(random.Next(
100)))
temp.Sort()
let height = ref 0
temp
|> Seq.iter
(
fun c ->
c.Top
<- !height
height := c.Height + !height)
temp.ToArray()

let myForm =
let temp = new Form() in
temp.Controls.AddRange(numberCtrls);
temp

[<STAThread
>]
do Application.Run(myForm)


在對象表達式makeNumberControl中,它繼承了Control類,同時也實現(xiàn)了IComparable接口。這里可以看到,在CompareTo方法中根據(jù)控件的Tag值進行比較,在調用Sort方法(ResizeArray即泛型類List<’T>)時會根據(jù)Compare方法對控件進行排序。排序完成后,依次呈現(xiàn)這些控件,如下圖:


對象表達式是一種強大的機制,可以幫助我們快速而簡潔地將非F#庫中的對象引入F#代碼。它的缺點則是沒法添加額外的屬性或方法。這也是在前面的例子中為何使用Tag屬性來存放n的值。

定義接口

接口僅包含抽象的方法和屬性。它為所有實現(xiàn)它的類定義了一份“契約”。F#中接口的概念與C#中的相同,在此不再贅述。如:

F# Code
type MyInterface = interface
abstract ChangeState : int -> unit
end


實現(xiàn)接口

實現(xiàn)接口的語法也很簡單。仍以上面的接口為例:

F# Code - 實現(xiàn)接口
type MyImpl = class
val mutable state : int
new() = { state = 0 }
interface MyInterface with
member x.ChangeState y = x.state <- y
end
end

let impl = new MyImpl()
let inter = impl :> MyInterface

let printIntAndNewLine i =
print_int i
print_newline()

let main() =
inter.ChangeState
1
printIntAndNewLine impl.state
inter.ChangeState
2
printIntAndNewLine impl.state

main()


運行結果為:

Output
1
2


不知你有沒有注意到,在調用ChangeState方法前,我們先將impl轉換為了MyInterface類型,否則不能調用。這是因為接口在F#中是顯式實現(xiàn)的,如果希望不經轉換就可以直接調用接口的方法,只能在類中在顯式地添加這個方法:-(

類、字段和顯式的構造函數(shù)

前面我們主要還是使用非F#庫中的類,現(xiàn)在來看看如何定義自己的類。

F# Code
#light
type EmptyClass = class
end

let emptyItem = new EmptyClass()


嗯,很明顯,這里試圖定義一個類,然后創(chuàng)建它的一個實例。不過編譯器不允許你這么做,它會告訴你:“error FS0191: No constructors are available for the type 'EmptyClass'”。沒有構造函數(shù)?如果你是C#程序員就會覺得奇怪了。事實上,F#沒有提供默認的構造函數(shù)這種機制,我們必須得手工添加一個,構造函數(shù)的名字總是為new

F# Code
type EmptyClass = class
new() = {}
end


另外,默認的構造函數(shù)容易使得字段不能正確地初始化,會給程序帶來隱患,而在F#中的構造函數(shù)必須初始化所有字段。使用val關鍵字定義字段,在下面的類MyFile中,它擁有兩個字段,path和innerFile,兩個字段在構造函數(shù)內進行初始化。

F# Code
#light
open System.IO

type MyFile = class
val path : string
val innerFile : FileInfo
new() = new MyFile("default.txt")
new(p) =
{ path = p;
innerFile =
new FileInfo(p) }
end


我們還可以看到,這個類有兩個構造函數(shù),也就是說構造函數(shù)可以重載。觀察構造函數(shù)new(p),它有一部分在{}內,這個代碼塊稱為構造函數(shù)的初始化塊,在這里唯一能做的事情就是初始化字段。如果想做更多的事情,就要在后面加then添加其它代碼:

F# Code
type MyFile2 = class
val path : string
val innerFile : FileInfo
new(p) as x =
{ path = p;
innerFile =
new FileInfo(p) }
then
if not x.innerFile.Exists then
let textFile = x.innerFile.CreateText()
textFile.Dispose()
end


new(p)后面加了as x,這樣就可以在后面的代碼中引用當前的對象了。then后面的代碼首先檢查文件是否存在,如果不存在就創(chuàng)建一個新文件。

注意:上面兩個類MyFile和MyFile2中的字段都是只讀的,如果需要修改它們,可以在字段名字前面添加關鍵字mutable,如val mutable innerFile;同時它們的訪問修飾符都是public,在下一篇文章將介紹如何在類中定義屬性。

思考:在函數(shù)式編程(下)中,曾介紹過自定義的記錄類型,比如

F# Code
type couple = { him : string; her : string }


那么這里的couple類和上面的MyFile類主要有哪些區(qū)別呢?請出我們的老朋友.NET Reflector來吧。在Reflector中打開編譯過的F#程序集可以看到,couple的類型定義為:

Type Infomation
public sealed class couple : IStructuralHash, IComparable


這是一個sealed類,這意味著無法繼承它,其中的her和him都是只讀屬性。
而MyFile的定義則是:

Type Infomation
public class MyFile


這個就跟C#中常規(guī)類的定義一致了,其中的path和innerFile都是只讀屬性。

隱式的類構造(Implicit Class Construction)

除了上面的顯式構造函數(shù),F#還支持隱式的類構造語法這樣的語法更為緊湊。它允許在定義類的成員前執(zhí)行一系列的let值綁定語句,這些綁定屬于類的私有部分

F# Code - 隱式的類構造
#light
open System.IO

type MyOtherFile(path) = class
let innerFile = new FileInfo(path)
member x.InnerFile = innerFile
end


我覺得對于前面的(顯式的類構造)MyFile類定義,這里的MyOtherFile類當然更為緊湊,看起來在定義類的同時就定義了構造函數(shù),隨后馬上初始化了字段,不過這里的innerFile已經是私有的了,所以再添加一個屬性InnerFile來公開innerFile字段。

隱式的類構造要比等價的顯式類構造代碼少很多,但是有時必須要用顯式的類構造,比如編寫擁有多個構造函數(shù)的類的時候。

小結

本文首先介紹了強大的對象表達式機制,通過它,我們可以快速地創(chuàng)建抽象類或接口的輕量級實現(xiàn);接下來是定義和實現(xiàn)接口;最后介紹了如何創(chuàng)建和實例化一個類,在創(chuàng)建類實例的時候,我們既可以采用顯式的構造函數(shù),也可以采用更為緊湊的“隱式的類構造”機制。

F#系列隨筆索引

注意:本文中的代碼均在F# 1.9.4.17版本下編寫,在F# CTP 1.9.6.0版本下可能不能通過編譯。

參考:
《Foundations of F#》 by Robert Pickering
《Expert F#》 by Don Syme , Adam Granicz , Antonio Cisternino
《F# Specs》

總結

以上是生活随笔為你收集整理的F#探险之旅(四):面向对象编程(中)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人啪啪 | 日韩一区二区a片免费观看 伊人网综合在线 | a毛片网站| 玉女心经是什么意思 | av日韩不卡 | 天天爽夜夜 | 免费看黄色av | 黄色福利片 | 国产黄页 | 欧美热热| 男人午夜剧场 | 成年人网站免费在线观看 | 国产精品99一区二区三区 | 91口爆一区二区三区在线 | 中文字幕精品三区 | 久久美利坚 | 毛片一级在线观看 | 国产精品视频 | 男人的天堂国产 | 欧美亚洲精品在线观看 | 成人毛片av| 欧美嫩草影院 | 亚洲福利| 欧美做受喷浆在线观看 | 一级特黄性色生活片 | 毛片无遮挡 | 蜜桃一区二区三区 | 1024亚洲天堂 | 婷婷色九月 | 欧美性大战久久久久久久蜜桃 | www.桃色| 亚洲成人一区二区三区 | 亚洲电影一区二区 | 黄色午夜| 成年人深夜福利 | 杨幂毛片 | 美女扒开腿让男人捅 | 欧美少妇性生活 | 亚洲一区二区三区精品视频 | 欧美激情一区二区三区p站 欧美mv日韩mv国产网站app | 五月色丁香 | 亚洲国产成人精品女人久久 | 日韩成人精品在线观看 | 国产日| 国产69精品久久久久久久久久 | 99自拍视频| 欧美人与动牲交xxxxbbbb | 国产精品自拍一区 | 伊人3| 医生强烈淫药h调教小说视频 | 亚洲av成人精品一区二区三区 | 三级伦理片 | 国产精品久久综合 | 青草草在线观看 | 色综合99久久久无码国产精品 | 亚洲一级一级 | 久久噜噜色综合一区二区 | 小泽玛利亚一区二区三区在线观看 | 日日人人 | 欧美视频免费看 | 精品国产999久久久免费 | 亚洲精品免费观看 | 波多野结衣小视频 | 国产精品久久免费 | 久久婷婷热| 一级特黄aa大片 | 免费av看 | 亚洲人屁股眼子交1 | 又黄又湿的网站 | 激情春色网 | 亚洲久久综合 | 欧美亚洲精品一区 | 人妻人人澡人人添人人爽 | 69re视频| 天天干天天爽天天操 | av有码在线观看 | 美女综合网 | 久久五月综合 | 麻豆一区二区三区 | 屁屁影院国产第一页 | 亚洲色图偷 | 中国videosex高潮hd | 免费在线看黄网站 | 日韩在线视频免费看 | 伊人夜色 | 日韩a级片在线观看 | 综合xx网 | 欧美r级在线观看 | 欧美一级性 | 久久久欧美 | 蜜桃视频久久一区免费观看入口 | jk美女又爽又黄视频 | 色多多在线观看 | 麻豆成人在线观看 | 久久久国产精品黄毛片 | 国产一国产二国产三 | 欧美日韩视频一区二区三区 | 成人在线视频免费观看 | 91日韩 |