函数式对象
这次写点关于函数式对象的吧
class Rational(n:Int, d:Int) { // n,d 为类参数,scala会创造出同样带有这两个参数的主构造器。如果这个类没有主体,可以不写大括号。
println(n+"/"+d)// scala 会把类内部既不是字段也不是方法定义的代码编译至主构造器。因此,该命令 会在实例化对象的时候被执行。
require(d != 0 ) //先决条件。先决条件是对传递给方法或者是构造器的值的限制,是调用者必须要满足的要求。如果失败抛出异常。
override def toString: String = n +"/"+d // override 重写某个函数 返回值类型可以省略,只有一行运算,所以花括号可以省略。这个函数的作用类似与python的 __str__ 或者是 __repr__
private val g = gcd(n.abs,d.abs) // 调用 下面的gac() 私有方法,得到最大公约数。abs方法用于获得绝对值。
val number: Int = n / g // 这两行代码是对下面两行代码的优化,用于将 分子分母 约分 例如 4/6 约成 2/3
val denom: Int = d / g
//val number: Int = n //注释1
//val denom: Int = d //注释2 这类似于 python的 def __init__(n,d) 下面的 self.number = n self.denom = d.将参数赋值给对象的字段。供对象调用
def add(that:Rational):Rational={
new Rational(
// n * that.d + that.n * d, d * that.d)//这么是不对的。that代表另一个Rational对象,但是n,d,并没有成为Rational对象的字段。n d只能在这个程序里面访问。所以要先进行注释1 和注释2
number * that.denom + that.number * denom, denom * that.denom)
}
def + (that:Rational):Rational={ //定义 操作符 + 以后可以 r1 + r2 其实是 r1.+(r2)
new Rational(
number * that.denom + that.number * denom, denom * that.denom)
}
def * (that:Rational):Rational = { //定义 * 操作符 以后可以 r1 * r2
new Rational(number * that.number, denom * that.denom) // 这里就省略了 this 直接用的 number 而不是 this.number
}
def lessThan(that:Rational) = {//这里省略了返回值类型。是一个布尔值。Boolean
this.number * that.denom < this.denom * that.number // 自指向 this。感觉类似于python的 self,是指当前类的实例,此种情况可以省略。
}
def max(that: Rational):Rational = {
if (this.lessThan(that)) // 这个this 也可以省略,默认调用自己的方法嘛。。
that
else
this //这里是指这个 Rational 对象本身,所以这种情况,this 肯定是不能省略的。
}
def this(n:Int) = this(n,1) //辅助构造器。主构造器以外的所有构造器。以 def this()开始。每个辅助构造器的第一个动作都是调用同类的别的构造器。但所有的构造器都是以调用主构造器结尾,因此主构造器是类的唯一入口。
// scala 里面,只有主构造器可以调用超类构造器。
private def gcd(a:Int, b:Int):Int = {
if (b == 0)
a
else
gcd(b, a%b)
/*
a b
6 4
a b
4 2
a b
2 0
a
2
*/
}
}
命名惯例
类/特质:驼峰式,第一个字母大写 单词首字母大写 如:class ReadBook
函数: 驼峰式 第一个字母小写 首字母大写 如:def readBook
常量: 驼峰式 首字母大写 如:val Readbook
字面量标识符
``
用反引号包裹的任何字符串。
你可以把运行时环境认可的任意字符串放在反引号之间当作标识符。结果总被scala当作标识符。即使反引号之间的字符串是scala保留字。这个规则也有效。如:在java 的Thread类中访问静态的yield 方法是它的典型应用。你不能写作Thread.yield(),因为yield 是scala保留字。但是你可以如下写法: