函数式对象
创建Rational
开始设计Rational类的着手点是考虑客户程序员将如何创建一个新的Rational对象。假设我们已决定让Rational对象是不可变的,我们将需要那个客户在创建实例时提供所有需要的数据(本例中,是分子和分母)。因此,我们应该这么开始设计:
class Rational(n: Int, d: Int)
Scala编译器将把你放在类内部的任何不是字段的部分或者方法定义的代码,编译进主构造器
class Rational(n: Int, d: Int){
println("created:" + n + " / " + d) //在主构造方法中,会执行
}
重新实现toString方法
class Rational(n: Int, d: Int) {
/**
* 重写 toString 方法
* if 条件之后的表达式作为返回结果,这一点和java不同
* @return
*/
override def toString: String = if (d == 1) n + "" else n + " / " + d
}
检查先决条件
class Rational(n: Int, d: Int){
//先决条件判断
// 这里实际调用了PreDef类的方法,scala默认引入PreDef类
require(d != 0)
}
添加字段
class Rational(n: Int, d: Int) {
require(d != 0)
val numer: Int = n
val denom: Int = d
override def toString = numer+"/"+denom
def add(that: Rational): Rational = new Rational( numer * that.denom + that.numer * denom, denom * that.denom )
}
自指向
关键字this指向当前执行方法被调用的对象实例,或者如果使用在构造器里的话,就是正被构建的对象实例。例如,我们考虑添加一个方法,lessThan,来测试给定的分数是否小于传入的参数:
class Rational(n: Int, d: Int) {
//定义比较大小的方法
//this 表示自引用
def lessThan(that: Rational): Boolean = this.numer * that.denom < this.denom * that.nume
}
辅助构造器
def this(n: Int) = this(n, 1)
私有字段和方法
private val g = gcd(n.abs, d.abs)
private def gcd(a: Int, b: Int): Int =
if (b == 0) a else gcd(b, a % b)
定义操作符和方法重载
//定义操作符
def + (that: Rational) = new Rational(numer * that.denom + denom * that.numer, denom * that.denom)
def - (that: Rational) = new Rational(numer * that.denom - denom * that.numer, denom * that.denom)
def * (that: Rational) = new Rational(numer * that.numer , denom * that.denom)
def / (that: Rational) = new Rational(numer * that.denom , denom * that.numer)
// 方法重载
def + (that: Int) = new Rational(numer + denom * that, denom)
def - (that: Int) = new Rational(numer - denom * that, denom)
def * (that: Int) = new Rational(numer * that , denom)
def / (that: Int) = new Rational(numer , denom * that)
隐式转换
implicit def intToRational(x: Int): Rational = new Rational(x)
object Rational {
def main(args: Array[String]): Unit = {
val ratio1 = new Rational(1, 2)
// val ratio2 = new Rational(2, 4)
//val ratio3 = new Rational(2)
//print(ratio)
// 为什么能够识别出来优先级呢?
//println(ratio1 + ratio2 * ratio3)
print(ratio1 + 2)
implicit def intToRational(x: Int): Rational = new Rational(x)
//不加隐式转换这里会出错
print(2 + ratio1)
}
}
//隐式转换
class Rational(n: Int, d: Int) {
//n = 3;//Reassignment to val
//先决条件判断
// 这里实际调用了PreDef类的方法,scala默认引入PreDef类
require(d != 0)
//私有化变量
private val g = gcd(n.abs, d.abs)
//添加成员
// 解决 n 和 d 不能直接被 方法引用的问题
val numer = n / g
val denom = d / g
println("created:" + n + " / " + d) //在主构造方法中,会执行
//辅助构造方法,会调用主构造方法,
//需求: 2 可以表示为 2/1. 如果只写一个2,默认分母是1
//构造方法的创建比java更为严格
def this(n: Int) = this(n, 1)
/**
* 重写 toString 方法
*
* @return
*/
override def toString: String = if (d == 1) n + "" else n + " / " + d
//value n is not a member of com.ghq.ch6.Rational
// 执行报错
//def add(that : Rational): Rational = new Rational(n*that.d + d*that.n, d*that.d)
//定义加法
def add(that: Rational): Rational = new Rational(numer * that.denom + denom * that.numer, denom * that.denom)
//定义比较大小的方法
//this 表示自引用
def lessThan(that: Rational): Boolean = this.numer * that.denom < this.denom * that.numer
//私有化方法
private def gcd(a: Int, b: Int): Int =
if (b == 0) a else gcd(b, a % b)
//定义操作符
def + (that: Rational) = new Rational(numer * that.denom + denom * that.numer, denom * that.denom)
def - (that: Rational) = new Rational(numer * that.denom - denom * that.numer, denom * that.denom)
def * (that: Rational) = new Rational(numer * that.numer , denom * that.denom)
def / (that: Rational) = new Rational(numer * that.denom , denom * that.numer)
// 方法重载
def + (that: Int) = new Rational(numer + denom * that, denom)
def - (that: Int) = new Rational(numer - denom * that, denom)
def * (that: Int) = new Rational(numer * that , denom)
def / (that: Int) = new Rational(numer , denom * that)
}
网友评论