1. 创建类
创建一个脚本Hyena.scala
,内容如下:
yqtao@yqtao:~/scala$ cat Hyena.scala
class Hyena {
println("this is an class body")
//定义了方法go()
def go():String={"go home"}
}
//生成对象
val hyena = new Hyena
//调用函数
val h = hyena.go()
println(h)
执行:
yqtao@yqtao:~/scala$ scala Hyena.scala
this is an class body
go home
例如,定义一个加法类:
yqtao@yqtao:~/scala$ cat Sum.scala
class Sum {
private var sum=0
def add(b:Byte)={
b=1
sum+=b
}
}
运行:
yqtao@yqtao:~/scala$ scala Sum.scala
/home/yqtao/scala/Sum.scala:4: error: reassignment to val
b=1
^
one error found
可以看到其报错:重新赋值给val常量。
2. 类参数
yqtao@yqtao:~/scala$ cat ClassArg.scala
class ClassArg(a:Int,b:Int,c:Int){
def add():Int={a+b+c}
}
val ret = new ClassArg(1,2,3).add()
println(ret)
运行:
yqtao@yqtao:~/scala$ scala ClassArg.scala
6
yqtao@yqtao:~/scala$ cat ClassArg.scala
class ClassArg(args:Int*){
def add():Int={
var total = 0
for (i <- args) {
total += i
}
total
}
}
val ret = new ClassArg(1,2,3,4,5).add()
println(ret)
运行:
yqtao@yqtao:~/scala$ scala ClassArg.scala
15
如下面的一个例子:
yqtao@yqtao:~/scala$ cat Coffee.scala
class Coffee(val shots:Int = 2,
val decaf:Int = 0,
val milk:Boolean = false,
val toGo:Boolean = false,
val syrup:String = "") {
var result = ""
println(caf, decaf, milk, toGo, syrup)
def getCup():Unit = {
if(toGo) {
result += "ToGoCup "
} else {
result += "HereCup "
}
}
def caf():Int = {
shots - decaf
}
def pourShots():Unit = {
for(s <- 0 until shots) {
if(decaf > 0) {
result += "decaf shot "
} else {
result += "shot "
}
}
}
def addMilk():Unit = {
if(milk) {
result += "milk "
}
}
def addSyrup():Unit = {
result += syrup
}
getCup()
pourShots()
addMilk()
addSyrup()
}
val usual = new Coffee
println(usual.result)
运行:
yqtao@yqtao:~/scala$ scala Coffee.scala
(2,0,false,false,)
HereCup shot shot
1. 类参数中定义变量可以被类中的函数使用,并且使用了默认的缺省值
2. 在类中进行了函数的调用,所以result的值不为空
3. val usual = new Coffee使用了类参数的缺省值构造对象
3. 辅助构造器
1 class Rational(n:Int,d:Int){
2 require(d!=0)
3 def this(n:Int)={
4 this(n,1)
5 }
6 }
d!=0
.
4. 定义对象运算
如下定义了一个有理数的类,其中定义了两个对象的+,*法操作:
yqtao@yqtao:~/scala$ cat Rational.scala
class Rational (n:Int, d:Int) {
require(d!=0)
private val g =gcd (n.abs,d.abs)
val numer =n/g
val denom =d/g
override def toString = numer + "/" +denom
def +(that:Rational) =
new Rational(
numer * that.denom + that.numer* denom,
denom * that.denom
)
def * (that:Rational) =
new Rational( numer * that.numer, denom * that.denom)
def this(n:Int) = this(n,1)
private def gcd(a:Int,b:Int):Int =
if(b==0) a else gcd(b, a % b)
}
val x = new Rational(1,10)
val y = new Rational(3,10)
val z = x + y
println(x)
println(y)
println(z)
val d = x*y
println(d)
看一下这个:
def +(that:Rational) =
new Rational(
numer * that.denom + that.numer* denom,
denom * that.denom
)
定义了一个+
运算符,另个类加法生成一个新的类,然后用主构造函数进行初始化。
运行结果如下:
yqtao@yqtao:~/scala$ scala Rational.scala
1/10
3/10
2/5
3/100
5. 方法重载
同C++一样,Scala也支持重载函数,最简单的重载方式:
// 注意可以类型推导不用写返回值
def add(a:Int,b:Int)={a+b}
def add(a:Double,b:Double)={a+b}
下面对+
进行重载:
def + (i:Int) =
new Rational (numer + i * denom, denom)
+
操作,可以实现x+1
这样的操作,返回一个新的对象。
yqtao@yqtao:~/scala$ cat Rational.scala
class Rational (n:Int, d:Int) {
require(d!=0)
private val g =gcd (n.abs,d.abs)
val numer =n/g
val denom =d/g
override def toString = numer + "/" +denom
def +(that:Rational) =
new Rational(
numer * that.denom + that.numer* denom,
denom * that.denom
)
def * (that:Rational) =
new Rational( numer * that.numer, denom * that.denom)
def this(n:Int) = this(n,1)
private def gcd(a:Int,b:Int):Int =
if(b==0) a else gcd(b, a % b)
def + (i:Int) =
new Rational(numer + i*denom,denom)
}
val x = new Rational(1,10)
val y = x + 1
println(y)
运行:
yqtao@yqtao:~/scala$ scala Rational.scala
11/10
2+x
则会报错,因为2不是一个有理数的对象,因此不能使用其+
.
yqtao@yqtao:~/scala$ scala Rational.scala
/home/yqtao/scala/Rational.scala:21: error: overloaded method value + with alternatives:
(x: Double)Double <and>
(x: Float)Float <and>
(x: Long)Long <and>
(x: Int)Int <and>
(x: Char)Int <and>
(x: Short)Int <and>
(x: Byte)Int <and>
(x: String)String
cannot be applied to (this.Rational)
val y = 2 + x
^
one error found
implicit def intToRational(x:Int) = new Rational(x)
参考资料:
1. 《scala编程思想》
2. https://www.shiyanlou.com/courses/490