扩展一个类:
可以扩展scala类以类似的方式,如在Java中的一样,但有两个限制:方法重载需要override关键字,只有主构造可以传递参数给基构造。现在扩展上面的类,并增加一个类的方法:
class Yiibai(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("Yiibai x location : " + x);
println ("Yiibai y location : " + y);
}
}
class Location(override val xc: Int, override val yc: Int,
val zc :Int) extends Yiibai(xc, yc){
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("Yiibai x location : " + x);
println ("Yiibai y location : " + y);
println ("Yiibai z location : " + z);
}
}
extends子句有两种作用:它使类Location继承类Yiibai所有非私有成员,它使Location类 作为Yiibai类的子类。 因此,这里的Yiibai类称为超类,而Location类被称为子类。扩展一个类,继承父类的所有功能,被称为继承,但 scala允许继承,只能从一个唯一的类。让我们看看完整的例子,显示继承的用法:
import java.io._
class Yiibai(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("Yiibai x location : " + x);
println ("Yiibai y location : " + y);
}
}
class Location(override val xc: Int, override val yc: Int,
val zc :Int) extends Yiibai(xc, yc){
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("Yiibai x location : " + x);
println ("Yiibai y location : " + y);
println ("Yiibai z location : " + z);
}
}
object Test {
def main(args: Array[String]) {
val loc = new Location(10, 20, 15);
// Move to a new location
loc.move(10, 10, 5);
}
}
需要注意的是方法move,不会覆盖 move 方法相应的定义,因为它们是不同的定义(例如,前两个参数,而后者则需要三个参数)。
让我们编译和运行上面的程序,这将产生以下结果:
C:/>scalac Test.scala
C:/>scala Test
Yiibai x location : 20
Yiibai y location : 30
Yiibai z location : 20
C:/>
单例对象:
Scala比Java更面向对象,因为在Scala中不能有静态成员。相反,Scala有单例的对象。单例就是只能有一个实例,即,类的对象。可以使用关键字object代替class关键字,而不是创建单例。因为不能实例化一个单独的对象,不能将参数传递给主构造。前面已经看到全部采用单一对象,调用 Scala的main方法的例子。以下是单例显示的相同的例子:
import java.io._
class Yiibai(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
}
}
object Test {
def main(args: Array[String]) {
val yiibai = new Yiibai(10, 20)
printYiibai
def printYiibai{
println ("Yiibai x location : " + yiibai.x);
println ("Yiibai y location : " + yiibai.y);
}
}
}
当上述代码被编译和执行时,它产生了以下结果:
C:/>scalac Test.scala
C:/>scala Test
Yiibai x location : 10
Yiibai y location : 20
C:/>
特性封装方法和字段定义,然后可以通过将它们混合成类被重用。不同于类继承,其中每个类都必须继承只有一个父类,一类可以在任意数量特质混合。
特征用于通过指定支持的方法的签名定义的对象类型。Scala中也允许部分实现特性但可能不具有构造参数。
一个特征定义看起来就像不同的是它使用关键字trait如下类定义:
trait Equal {
def isEqual(x: Any): Boolean
def isNotEqual(x: Any): Boolean = !isEqual(x)
}
这种特质由两个方法的isEqual和isNotEqual。这里,我们没有给出任何实现的isEqual其中作为另一种方法有它的实现。扩展特性的子类可以给实施未实现的方法。因此,一个特点是非常相似Java的抽象类。下面是一个完整的例子来说明特性的概念:
trait Equal {
def isEqual(x: Any): Boolean
def isNotEqual(x: Any): Boolean = !isEqual(x)
}
class Yiibai(xc: Int, yc: Int) extends Equal {
var x: Int = xc
var y: Int = yc
def isEqual(obj: Any) =
obj.isInstanceOf[Yiibai] &&
obj.asInstanceOf[Yiibai].x == x
}
object Test {
def main(args: Array[String]) {
val p1 = new Yiibai(2, 3)
val p2 = new Yiibai(2, 4)
val p3 = new Yiibai(3, 3)
println(p1.isNotEqual(p2))
println(p1.isNotEqual(p3))
println(p1.isNotEqual(2))
}
}
当上述代码被编译和执行时,它产生了以下结果:
C:/>scalac Test.scala
C:/>scala Test
false
true
true
C:/>
什么时候使用特性?
没有严格的规定,但这里有一些指导原则需要考虑:
· 如果行为不被重用,则要使它成为一个具体的类。它毕竟不是可重复使用的行为。
· 如果它可能在多个不相关的类被重用,使它成为一个性状。只有特性可混入的类层次结构的不同部分。
· 如果想它从继承Java代码,使用抽象类。
· 如果打算在已编译的形式分发,而且希望外部组织编写的类继承它,可能会倾向于使用抽象类。
· 如果效率是非常重要的,倾向于使用类。
模式匹配是Scala中第二个最广泛使用的功能,经过函数值和闭包。Scala中大力支持模式匹配处理消息。
模式匹配包括替代的序列,每个开始使用关键字case。每个备选中包括模式和一个或多个表达式,如果模式匹配将被计算。一个箭头符号=>分开的表达模式。这里是一个小例子,它展示了如何匹配一个整数值:
object Test {
def main(args: Array[String]) {
println(matchTest(3))
}
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "many"
}
}
当上述代码被编译和执行时,它产生了以下结果:
C:/>scalac Test.scala
C:/>scala Test
many
C:/>
使用case语句块定义一个函数,该函数映射整数字符串。匹配关键字提供应用函数(如模式匹配函数以上)为一个对象的一个方便的方法。下面是第二个示例,它匹配针对不同类型的模式值:
object Test {
def main(args: Array[String]) {
println(matchTest("two"))
println(matchTest("test"))
println(matchTest(1))
}
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int"
case _ => "many"
}
}
当上述代码被编译和执行时,它产生了以下结果:
C:/>scalac Test.scala
C:/>scala Test
2
many
one
C:/>
第一个case ,如果 x 指的是整数值1. 如果x等于字符串“2”的第二case相匹配匹配。第三种case 是由一个输入模式;它匹配针对任何整数,并结合选择值xto整数类型的变量y。以下为文字相同的匹配... case 表达式用括号 {...} 另一种形式:
object Test {
def main(args: Array[String]) {
println(matchTest("two"))
println(matchTest("test"))
println(matchTest(1))
}
def matchTest(x: Any){
x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int"
case _ => "many"
}
}
}
from: http://www.yiibai.com/scala/scala_basic_syntax.html