您的位置:首页 > 编程语言

F#程序设计-面向对象编程之类的定义

2009-12-29 08:59 134 查看
F#的面向对象编程与其他的.NET语言总体上没有什么多大的区别,除了语法上有些区别之外。在用户自定义类型当中,类(class)可能定义最频繁的类型吧,F#有两个独特的语法来定义类的构造函数:显式构造与隐式构造。前者更符合F#简单而又简洁的语法,而后者允许更明确的控制类是如何产生的。

一、显式构造

显式构造是相对于隐式构造来说虽然看来没有那么灵活,但是它提供了最大的控制。当你使用显式构造来定义一个类时,你必须明确类中的每个字段名称,并且在构造函数中初始化它们。

显式构造定义的类中,定义字段需要用val关键字,并通过自我标识来访问字段(比如this.field)。下面的代码段定义了一个类Point以及两个字段m_x、m_y。同时定义了连个构造函数,其中一个带有两个参数,一个没有:

type Point =

val m_x :float

val m_y :float



new(x,y) = { m_x = x ; m_y = y }

new() = { m_x = 0.0 ; m_y = 0.0 }

let point = new Point()

let point1 = new Point(2.0,3.0)


在C#中,如果没有提供构造函数,则C#会默认提供一个构造函数,然后在F#中就必须定义构造函数,如果没有,那么将无法实例这个类。

你可以在类的字段初始化之前或者之后执行一个有限的设置动作。要执行一个动作,只需简单的在初始化字段后,在"="之后简单的编写执行代码即可。初始化字段后为了能够执行设置动作,利用then关键字并且后面接着表达式,同时需要注意的是表达式并需返回unit:

type Point =

val m_x :float

val m_y :float



new(x,y) as this =

{ m_x = x ; m_y = y }

then

printfn "Initialized to [%f, %f]" this.m_x this.m_y


在显式构造中,无论是成员还是字段,在调用时都需要带一个自我标识前缀,像上面的this.m_x。然后,这个自我标识可以是自定义的,不一定就是this做前缀。在方法、属性或者构造函数中如果采用了自定义标识,则相应的代码段内,调用的其他成员或者字段,采用的自我标识前缀必须定义构造函数、方法中的自我标识相同,否早编译不通过。比如可以把上面的代码中的this改成self或者其它:

new(x,y) as self=

{ m_x = x ; m_y = y }

then

printfn "Initialized to [%f, %f]" self.m_x self.m_y





二、隐式构造

虽然显式定义类跟典型的面向对象编程风格有相似之处,但是在函数编程风格中似乎看起啦相当的不自然。隐式构造提供了一种简单的方式来定义类,并且在F#中看起来它更适合更自然些。在隐式构造定义类中,没有了在显式构造中的明确字段(val 绑定)。相反,它采用let绑定来定义内部类型。当类被编译后,let绑定将被编译成字段并且做简单的优化。所以,在利用隐式构造来定义的类中,不允许明确定义一个字段。



要创建一个隐式的构造类型,只需在类的后面添加括号和参数,该参数将作为该类型的主要构造函数参数。在类的结构体内let绑定或者do绑定将会在类实例化是执行。定义其他构造函数最终必须调用主要构造函数,以确保所有let绑定被初始化:

type Point3( x : float , y : float ) =

let m_x = x

let m_y = y

do printfn "Initialized to [%f, %f]" m_x m_y

new() = new Point3(0.0, 0.0)

let point3 = new Point3(3.0,2.0)

主要构造函数中的参数以及定义的let绑定(m_x、m_y),可以在类内任何地方被调用而采用像显式构造中的自我标识做前缀。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: