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。

    正如这个例子所示,访问成员函数与访问字段一样,都通过点符号来进行访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值