F#入门-第四章 面向对象-第三节 成员函数
2010-09-20 15:04
190 查看
■ 成员函数
上一节我们学习了给类添加字段的方法,本节介绍如何让类具有成员函数.如前所述,类所具有的函数叫做方法或成员函数。
将定义成员函数的书写方法提取如下
成员函数的定义 类定义 :=
type 类名 [ 模式 ] [ as 识别符 ] =
class
...
[元素类型定义]*
end
元素类型定义 :=
| 成员定义
| ...
成员定义 :=
| [ static ] member 成员绑定
| ...
成员绑定 :=
| [ 识别符 '.' ] 绑定
| [ 识别符 '.' ] 识别符 with 绑定
因为光看以上描述是很难理解的,所以让我们来看个例子,该例子定义三个成员函数与一个属性。
成员函数的定义
member是声明成员时用的关键字。在这之后,以“类本身的引用名.成员函数名模式1...=函数体”的形式定义了函数。将member关键字与类本身的引用名这一部分去除掉,就与普通函数定义没什么区别了。当然,成员函数也可以进行柯里化,可以用别的变量来代替,调用函数时,采用对象名.成员函数名的形式进行调用。
使用类本身的引用名是为了从函数体内部可以访问自身类中进行定义的其他成员,通常类本身的引用名为x或v等很短小的名字,或this,self这类名字。这个例子中使用了x为类自身的引用名,可以通过x.data来引用x的成员data的值。另外,可以象prop成员那样,定义不带参数的成员。
■ 静态成员函数
成员函数基本上是通过对象来进行调用的,但是如果加上static关键字,就可以通过类来进行调用了。因此,声明静态函数时,不需要加上类自身的引用名。
象数学计算用类这样的不需要具体对象的类经常调用静态成员函数。在下例中,定义了一个非常简单的Math类,该类具有一个返回数值绝对值的静态成员函数。
静态成员函数
象这样,采用类名.函数名的形式来调用静态成员函数。
■ 将记录类型作为对象使用
在介绍记录类型的时候并没有对此进行介绍。记录可以具有除字段之外的其他成员。因此,可以用记录来模拟对象。
采用如下所示方法给记录定义成员函数。成员函数名前面的类型名相当于对类进行定义时类本身的引用名。
具有成员函数的记录的定义 type 类型名 = { 字段名1 : 类型名1; ... ; 字段名n : 类型名n }
with
member 类型名1.成员函数名1 模式1 ... 模式n = 函数体
..
member 类型名n.成员函数名n 模式1 ... 模式n = 函数体
end
通过这种方法,可以创建表示点坐标的记录.
Point类型的利用
Point类型是只带有x与y的值的简单数据类型,带有显示字段值的show方法与接受另一个Point类型的参数(作为移动的向量)的方法move。
正如这个例子所示,访问成员函数与访问字段一样,都通过点符号来进行访问。
上一节我们学习了给类添加字段的方法,本节介绍如何让类具有成员函数.如前所述,类所具有的函数叫做方法或成员函数。
将定义成员函数的书写方法提取如下
成员函数的定义 类定义 :=
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);; |
使用类本身的引用名是为了从函数体内部可以访问自身类中进行定义的其他成员,通常类本身的引用名为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();; |
正如这个例子所示,访问成员函数与访问字段一样,都通过点符号来进行访问。
相关文章推荐
- F#入门-第四章 面向对象-第一节 对象
- F#入门-第四章 面向对象-第七节 接口
- F#入门-第四章 面向对象-第八节 对象表达式
- F#入门-第四章 面向对象-第四节 封装
- F#入门-第四章 面向对象-第五节 继承
- F#入门-第四章 面向对象-第十一节 活动模式
- F#入门-第四章 面向对象-第二节 类与构造器
- 【算法竞赛入门经典】第四章:函数和递归笔记和代码
- 算法竞赛入门经典: 第四章 函数与递归 4.1求两点之间距离
- C++面向对象—成员函数与成员变量的实现机制学习笔记(1)
- 【PHP面向对象(OOP)编程入门教程】6.如何去使用对象中的成员
- [NET]Net中的反射使用入门(根据类名和函数名,生成和调用对象的成员函数) (转)
- 算法竞赛入门经典: 第四章 函数与递归 4.2组合数
- [NET]Net中的反射使用入门(根据类名和函数名,生成和调用对象的成员函数) .
- 完美的C++面向对象之友元类,静态成员函数
- PERL语言入门:第四章:子程序(函数)
- 算法竞赛入门经典: 第四章 函数与递归 4.3孪生素数
- 【C++面向对象】类的静态成员函数(static member functions)
- PERL语言入门:第四章:子程序(函数) :调用子程序与子程序返回值
- 算法竞赛入门经典: 第四章 函数与递归 4.4变量交换