您的位置:首页 > 其它

Scala基础教程(七):类和对象、特征

2015-12-10 12:36 288 查看

扩展一个类:

可以扩展scala类以类似的方式,如在Java中的一样,但有两个限制:方法重载需要override关键字,只有主构造可以传递参数给基构造。现在扩展上面的类,并增加一个类的方法:

classYiibai(valxc:Int,valyc:Int){

varx:Int=xc

vary:Int=yc

defmove(dx:Int,dy:Int){

x=x+dx

y=y+dy

println("Yiibaixlocation:"+x);

println("Yiibaiylocation:"+y);

}

}


classLocation(overridevalxc:Int,overridevalyc:Int,

valzc:Int)extendsYiibai(xc,yc){

varz:Int=zc


defmove(dx:Int,dy:Int,dz:Int){

x=x+dx

y=y+dy

z=z+dz

println("Yiibaixlocation:"+x);

println("Yiibaiylocation:"+y);

println("Yiibaizlocation:"+z);

}

}

extends子句有两种作用:它使类Location继承类Yiibai所有非私有成员,它使Location类作为Yiibai类的子类。因此,这里的Yiibai类称为超类,而Location类被称为子类。扩展一个类,继承父类的所有功能,被称为继承,但scala允许继承,只能从一个唯一的类。让我们看看完整的例子,显示继承的用法:

importjava.io._


classYiibai(valxc:Int,valyc:Int){

varx:Int=xc

vary:Int=yc

defmove(dx:Int,dy:Int){

x=x+dx

y=y+dy

println("Yiibaixlocation:"+x);

println("Yiibaiylocation:"+y);

}

}


classLocation(overridevalxc:Int,overridevalyc:Int,

valzc:Int)extendsYiibai(xc,yc){

varz:Int=zc


defmove(dx:Int,dy:Int,dz:Int){

x=x+dx

y=y+dy

z=z+dz

println("Yiibaixlocation:"+x);

println("Yiibaiylocation:"+y);

println("Yiibaizlocation:"+z);

}

}


objectTest{

defmain(args:Array[String]){

valloc=newLocation(10,20,15);


//Movetoanewlocation

loc.move(10,10,5);

}

}

需要注意的是方法move,不会覆盖move
方法相应的定义,因为它们是不同的定义(例如,前两个参数,而后者则需要三个参数)。

让我们编译和运行上面的程序,这将产生以下结果:

C:/>scalacTest.scala

C:/>scalaTest

Yiibaixlocation:20

Yiibaiylocation:30

Yiibaizlocation:20


C:/>

单例对象:

Scala比Java更面向对象,因为在Scala中不能有静态成员。相反,Scala有单例的对象。单例就是只能有一个实例,即,类的对象。可以使用关键字object代替class关键字,而不是创建单例。因为不能实例化一个单独的对象,不能将参数传递给主构造。前面已经看到全部采用单一对象,调用Scala的main方法的例子。以下是单例显示的相同的例子:

importjava.io._


classYiibai(valxc:Int,valyc:Int){

varx:Int=xc

vary:Int=yc

defmove(dx:Int,dy:Int){

x=x+dx

y=y+dy

}

}


objectTest{

defmain(args:Array[String]){

valyiibai=newYiibai(10,20)

printYiibai


defprintYiibai{

println("Yiibaixlocation:"+yiibai.x);

println("Yiibaiylocation:"+yiibai.y);

}

}

}

当上述代码被编译和执行时,它产生了以下结果:

C:/>scalacTest.scala

C:/>scalaTest

Yiibaixlocation:10

Yiibaiylocation:20


C:/>

特性封装方法和字段定义,然后可以通过将它们混合成类被重用。不同于类继承,其中每个类都必须继承只有一个父类,一类可以在任意数量特质混合。

特征用于通过指定支持的方法的签名定义的对象类型。Scala中也允许部分实现特性但可能不具有构造参数。

一个特征定义看起来就像不同的是它使用关键字trait如下类定义:

traitEqual{

defisEqual(x:Any):Boolean

defisNotEqual(x:Any):Boolean=!isEqual(x)

}

这种特质由两个方法的isEqual和isNotEqual。这里,我们没有给出任何实现的isEqual其中作为另一种方法有它的实现。扩展特性的子类可以给实施未实现的方法。因此,一个特点是非常相似Java的抽象类。下面是一个完整的例子来说明特性的概念:

traitEqual{

defisEqual(x:Any):Boolean

defisNotEqual(x:Any):Boolean=!isEqual(x)

}


classYiibai(xc:Int,yc:Int)extendsEqual{

varx:Int=xc

vary:Int=yc

defisEqual(obj:Any)=

obj.isInstanceOf[Yiibai]&&

obj.asInstanceOf[Yiibai].x==x

}


objectTest{

defmain(args:Array[String]){

valp1=newYiibai(2,3)

valp2=newYiibai(2,4)

valp3=newYiibai(3,3)


println(p1.isNotEqual(p2))

println(p1.isNotEqual(p3))

println(p1.isNotEqual(2))

}

}

当上述代码被编译和执行时,它产生了以下结果:

C:/>scalacTest.scala

C:/>scalaTest

false

true

true


C:/>

什么时候使用特性?

没有严格的规定,但这里有一些指导原则需要考虑:

·如果行为不被重用,则要使它成为一个具体的类。它毕竟不是可重复使用的行为。

·如果它可能在多个不相关的类被重用,使它成为一个性状。只有特性可混入的类层次结构的不同部分。

·如果想它从继承Java代码,使用抽象类。

·如果打算在已编译的形式分发,而且希望外部组织编写的类继承它,可能会倾向于使用抽象类。

·如果效率是非常重要的,倾向于使用类。

模式匹配是Scala中第二个最广泛使用的功能,经过函数值和闭包。Scala中大力支持模式匹配处理消息。

模式匹配包括替代的序列,每个开始使用关键字case。每个备选中包括模式和一个或多个表达式,如果模式匹配将被计算。一个箭头符号=>分开的表达模式。这里是一个小例子,它展示了如何匹配一个整数值:

objectTest{

defmain(args:Array[String]){

println(matchTest(3))


}

defmatchTest(x:Int):String=xmatch{

case1=>"one"

case2=>"two"

case_=>"many"

}

}

当上述代码被编译和执行时,它产生了以下结果:

C:/>scalacTest.scala

C:/>scalaTest

many


C:/>

使用case语句块定义一个函数,该函数映射整数字符串。匹配关键字提供应用函数(如模式匹配函数以上)为一个对象的一个方便的方法。下面是第二个示例,它匹配针对不同类型的模式值:

objectTest{

defmain(args:Array[String]){

println(matchTest("two"))

println(matchTest("test"))

println(matchTest(1))


}

defmatchTest(x:Any):Any=xmatch{

case1=>"one"

case"two"=>2

casey:Int=>"scala.Int"

case_=>"many"

}

}

当上述代码被编译和执行时,它产生了以下结果:

C:/>scalacTest.scala

C:/>scalaTest

2

many

one


C:/>

第一个case,如果x指的是整数值1.如果x等于字符串“2”的第二case相匹配匹配。第三种case是由一个输入模式;它匹配针对任何整数,并结合选择值xto整数类型的变量y。以下为文字相同的匹配...case表达式用括号{...}另一种形式:

objectTest{

defmain(args:Array[String]){

println(matchTest("two"))

println(matchTest("test"))

println(matchTest(1))


}

defmatchTest(x:Any){

xmatch{

case1=>"one"

case"two"=>2

casey:Int=>"scala.Int"

case_=>"many"

}

}

}


from:http://www.yiibai.com/scala/scala_basic_syntax.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息