F#程序设计-面向对象编程之属性和方法

来源:互联网 发布:dota2淘宝黑货 编辑:程序博客网 时间:2024/05/19 00:53

类通过他们的方法和属性被赋予内涵。方法是一种动作,属于动词,描述类可以做什么或者它能这样做;属性,另一方面,则是形容词,它有助于类的描述。

 

一、定义属性

属性有三种不同的操作形式:只读、只写、读写。属性的读操作通过get关键字来定义,并且返回属性的值,而写操作,则是通过set关键字来更新属性的值。对于定义一个只读的属性,在语法上只需简单的定义一个方法并且无需参数。而另一种方式是,可以提供with get 或者 with set方法,比如下面的示例:

type Author =
            val mutable id : int
            val mutable last_name : string
            val mutable first_name : string

            // 简单的定义只读属性
            member this.First_Name = this.first_name

            // 通过with get定义只读属性
            member this.First_Name1  with get() = this.first_name

            // 定义可写属性
            member this.Last_Name with set newList_Name = this.last_name <- newList_Name

            // 定义可读可写属性
            member this.Id with get() = this.id
                            and set newId = this.id <- newId

            // 构造函数
            new() = {id = 0 ; last_name = "" ; first_name = ""}

 

在上篇介绍的类的定义的时候提到过在显式定义类的时候,无论是字段还是成员,在定义以及引用的时候都需要带上一个自我标识前缀(隐式定义类是只需要在成员中带上自我标识前缀)。同时,在定义值的时候,由于需要改变值,所以也别忘记了加上mutable关键字,否则,定义可写属性或者在方法中更新值将会导致编译异常。

 

二、在构造函数中设置属性值

属性C#的程序员应该知道,在C# 3.0提供了可以在构造函数中对属性进行赋值,如:

//C# 代码

Author author = new Author(){Last_Name = "jeooo",First_name="li"}

 

同样,在F#中,也提供了这种简单的方式来在实例化一个类的构造函数中对属性进行初始化:

        // F# 代码

        type Author() =
            let mutable last_name = ""
            let mutable first_name = ""
            // 定义可写属性
            member this.Last_Name with  get() = last_name
                                  and   set newList_Name = last_name <- newList_Name

            member this.First_Name with get() = first_name
                                   and set newfirstname = first_name <- newfirstname

 

然后,实例化对象时,我们就可以这样写:

let author = new Author(Last_Name = "jeoo" , First_Name = "li")

 

在这里,需要注意的是,只有在隐式定义类中才能这样做,在显式定义类中,就不能在构造函数中对属性进行初始化操作。

 

三、定义方法

在类中定义一个方法就是在指定自我标识后紧接着定义方法名即可。跟函数一样,在方法名后的任何形式的规则都是它的参数,如果没有参数,可以标记为unit 类型,比如下面的代码:

type Television =
            val mutable m_channel : int
            val mutable m_turnedOn : bool

            new() = { m_channel = 3; m_turnedOn = true }

            // 没有参数
            member this.TurnOn () =
                printfn "Turning on..."
                this.m_turnedOn <- true

            member this.TurnOff () =
                printfn "Turning off..."
                this.m_turnedOn <- false

            // 带有参数
            member this.ChangeChannel (newChannel : int) =
                if this.m_turnedOn = false then
                    failwith "Cannot change channel, the TV is not on."
                printfn "Changing channel to %d..." newChannel
                this.m_channel <- newChannel

 

除此之外,方法也可以像函数一样被定义,比如:

type Adder() =
            member this.AddTwoParams x y = x + y      
            member this.AddTwoTupledParams (x, y) = x + y

 

但是,在F#中的定义方法中,不建议利用第一种形式来定义方法,因为在.NET的其它语言中并不支持,最好的方法就是所有的参数都被放入一个元组中,像第二种方式。这样,当被其它.NET语言所引用时,你的F#代码看起来不像是一个单一的元素参数,而是元组中的那个值都是参数。另外,函数与类的方法中一个小小区别就是类的方法可以递归,并且无需采用关键字rec

 

在F#中,方法的重载跟.NET其它语言的方法重载规则一样,比如:

 type BitCounter =
            static member CountBits (x : int16) =
                    let mutable x' = x
                    let mutable numBits = 0
                    for i = 0 to 15 do
                        numBits <- numBits + int (x' &&& 1s)
                        x' <- x' >>> 1
                    numBits

            static member CountBits (x : int) =
                    let mutable x' = x
                    let mutable numBits = 0
                    for i = 0 to 31 do
                        numBits <- numBits + int (x' &&& 1)
                        x' <- x' >>> 1
                    numBits

            static member CountBits (x : int64) =
                    let mutable x' = x
                    let mutable numBits = 0
                    for i = 0 to 63 do
                        numBits <- numBits + int (x' &&& 1L)
                        x' <- x' >>> 1
                    numBits

 

 

四、静态方法、属性、字段

在F#中,如果类中的方法、属性无需实例对象就能直接访问,只需要把它标记为static,并且也无需自我标识,类的字段也是如此:

 type Author() =
            let mutable last_name = ""
            let mutable first_name = ""
            let mutable id = 0
            // 静态字段
            static let mutable m_instance = 0

            do
                // 类实例次数
                m_instance <- m_instance + 1

            member this.Last_Name with  get() = last_name
                                  and   set newList_Name = last_name <- newList_Name

            member this.First_Name with get() = first_name
                                   and set newfirstname = first_name <- newfirstname

            member this.Id with get() = id
                            and set newId = id <- newId

            override this.ToString() =
                            System.String.Format("author's name is{0} {1},ID is {2} and the instances is {3} ",first_name,last_name ,id,m_instance)
            // 静态方法
            static member FindById(id) =
                           printfn "get Author by id %d " id
                           let author = new Author(Id = id , Last_Name = "jeooo" , First_Name = "li")
                           author

 

原创粉丝点击