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

扩展一个类:

可以扩展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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值