Scala的函数式对象
本节主要是通过一个关于有理数的案例来说一些知识点。
包括几大方面:1.类的创建
2.重载方法
3.检查先决条件
4.添加字段
5.自指向
6.辅助构造器
7.私有字段和方法
8.定义操作符
9.隐士转换
先贴个代码哈!!!!!!
object Test{ def main(args: Array[String]): Unit = { val a = new Rational(1,2) println(a) val b = new Rational(2,3) println(b) val c = a add b println(c) println(c.m) println(c.n) println(c.comp) val d = new Rational(4) println(d) val e = new Rational(66,42) println(e) val f = new Rational(2,3) val g = new Rational(3) val h = f + g println(h) val i = new Rational(2,3) val j = new Rational(3,4) println(i*j) val k = new Rational(2,3) val l = new Rational(3,4) val m = new Rational(4,5) println(k+l*m) //*的优先级比+高,所以先计算l*m,在计算+ val n = new Rational(2,3) val o = new Rational(3) val p = n * o println(p) implicit def intToRational(i:Int):Rational = return new Rational(i)//隐士转换,将整形转换为Rational类型 val q = new Rational(3,4) val r = 2 println(r*q) } } //创建Rational类 class Rational(x: Int, y: Int){ require(y!=0) // 检查先决条件 def this(cnt:Int) = this(cnt,1) //辅助构造器,可以有多个,定义开始为def this(), // 被定义的构造器既可以是主构造器,也可以是其他构造器,因此主构造器才是类的唯一入口点 private val g = gcd(x.abs,y.abs) var m = x/g //对外可见的,public,如果没有var或者val修饰词,则是对外不可见的,private var n = y/g def add(r:Rational):Rational = { return new Rational(m*r.n+r.m*n,n*r.n) } def + (r:Rational):Rational = { return new Rational(m*r.n+r.m*n,n*r.n) } def + (i:Int):Rational = { return new Rational(m+i*n,n) } def - (r:Rational):Rational = { return new Rational(m*r.n-r.m*n,n*r.n) } def - (i:Int):Rational = { return new Rational(m-i*n,n) } def * (r:Rational):Rational = { return new Rational(m*r.m,n*r.n) } def * (i:Int):Rational = { return new Rational(m*i,n) } def / (r:Rational):Rational = { return new Rational(m*r.n,n*r.m) } def / (i:Int):Rational = { return new Rational(m,n*i) } def comp:Int = {if(this.m>this.n) return 1 else 0} // this关键字是自指向,指向的是调用该方法的对象和java的一样 override def toString = { if (n == 1) { m+"" } else { m + "/" + n } //override修饰符是对原方法的冲载 } //求两个数的最大公约数 private def gcd(x:Int,y:Int):Int = { if(y==0) return x else{ return gcd(y,x%y) } } }
知识点:
1.当我们重新实现某个函数的时候,比如toString方法,需要使用override关键字。
2.检查先决条件使用require(b:Boolean),参数是一个布尔型参数,当为真的时候继续执行,为假的时候将抛出IllegalArgumentException阻止对象被构造。
3.添加字段,首先确定该字段是否是对外可见,如果对外可见则必须带有val或者var修饰符,默认是public,如果不对外可见,则不需要写修饰符。
4.自指向指的就是this关键字,用法和java的一样,this指向的是调用该函数的对象。
5.有时候某个类可能会需要多个构造器,除了主构造器之外的都是辅助构造器,但是辅助构造器最终还会走到主构造器, 所以主构造器才是类的唯一入口,主构造器内的参数为类参数,类参数对外不可见,辅助构造器固定写法都是以def this(....)定义。
6.在类中也可以定义一些操作符,例如+,-,*,/等。在java或其他语言中,操作符就是一个运算符,但是在scala中,它们是函数。
7.方法重载的定义和java中一样,函数名一样,参数列表不一样,也就是方法签名不一样。
8.隐士转换,这个功能很是强大,但是能力越大,责任越大。我上面的代码都是使用类的对象去调用,但是当我们使用其他类型,例如整型,我们计算1+2/3时,是报错的,但我们使用隐士转换就会把1这个整数转换为我们定义的类型,这样就可以进行其他操作。隐士转换需使用关键字implicit。但是一定要确定好作用域,当超出使用的范围时,不会生效的。