函数式对象之介绍
博客专区 > 柳哥 的博客 > 博客详情
函数式对象之介绍
柳哥 发表于4年前
函数式对象之介绍
  • 发表于 4年前
  • 阅读 71
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

函数式对象这系列blog的重点在于定义函数式对象,也就是说,不具有任何可变状态的对象的类。为了便于说明和演示,我们将创造若干以有理数作为不可变对象来建模的类版本。在此过程中,我们会学习scala面向对象编程的更多知识:类参数构造函数方法操作符私有成员重写先决条件检查重载自指向

类Rational的规格说明书

有理数是一种可以表达为比率n/d的数字,这里的n和d是数字,其中d不能为零。n被称作分子,d被称作分母。有理数的例子有:1/2,2/3。
本章我们将要设计的类必须建模有理数的行为,包括允许它们执行加、减、乘、除运算。数学上有理数不具有可变的状态,有理数可以相加减,但结果是新的有理数,原来的数不会被改变。我们本章设计的不可变Rational类将秉承这一属性。每个有理数都能被表示成Rational对象,当两个Rational对象相加减时,将创建新的带着加减结果的Rational对象。

创建Rational类

着手设计Rational类之前应先考虑客户程序员将如何创建新的Rational对象。假如我们已经决定让Rational对象是不可变的,我们将需要那个客户在创建实例时提供所有需要的数据(本例中是分子、分母)。因此,我们应该这么开始设计:

package scalaTest
class Rational(n:Int,d:Int)

这行代码里首先应当注意到的是如果类没有主体,就不需要指定一对空的花括号(当然你如果想的话也可以)。在类名Rational之后的括号里的n和d,被称为类参数Scala编译器会收集这两个类参数并创造出带同样的两个参数的主构造器
另外,scala编译器将把类内部的任何既不是字段不是方法定义的代码编译至主构造器中。例如:

class Rational(n:Int,d:Int) {
    println("Created " + n + "/" + d)
}

scala编译器将把这段代码的println调用放进Rational的主构造器。因此,println调用将在每次创建新的Rational实例时打印这条信息。如:

不可变对象的权衡
不可变对象提供了若干强于可变对象的优点和一个潜在的缺点
首先,不可变对象常常比可变对象更易理清头绪,因为它们没有会随着时间变化复杂的状态空间。其次,你可以很自由地传递不可变对象,但对于可变对象来说,传递给其他代码之前,需要先建造个以防万一的副本。第三,一旦不可变对象完成构造之后,就不会有线程因为并发访问而破坏对象内部状态。因为根本没有线程可以改变不可变对象的状态。第四,不可变对象让哈希表键值更安全。比方说,如果可变对象在进入HashSet之后被改变,那么你下一次查找这个HashSet时就找不到这个对象了。不可变对象唯一的缺点就是有时需要复制很大的对象而可变对象的更新可以在原址发生。有些情况下这会变得难以快速完成而可能产生性能瓶颈。因此,要求功能库提供不可变类的可变版本也并非是一件稀奇的事情。例如:类StringBuilder是不可变的String的可变版本。

注意
这个Rational例子凸显了Java与scala之间的不同。Java类具有可以带参数的构造器,而scala类可以直接带参数。Scala的写法更简洁------类参数可以直接在类的主体中使用,没必要定义字段然后写赋值函数把构造器的参数复制到字段里

标签: scala
共有 人打赏支持
粉丝 200
博文 394
码字总数 347782
×
柳哥
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: