码迷,mamicode.com
首页 > 其他好文 > 详细

scala 学习笔记(04) OOP(中)

时间:2015-08-12 01:12:34      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:

一、trait 不仅仅只是接口!

scala是一个非常有想法的语言,从接口的设计上就可以发现它的与众不同。scala中与java的接口最接近的概念是trait,见下面的代码:

package yjmyzz


object App {

  def main(args: Array[String]) {
    val bird = Bird("pigeon")
    bird.fly
    println(bird.isInstanceOf[Bird]) //true
    println(bird.isInstanceOf[Flyable]) //true
    println(bird.toString) //this is a Bird:pigeon
    bird.test //hello
  }
}

/**
 * 定义一个"接口"
 */
trait Flyable {

  /**
   * 定义接口方法
   */
  def fly;


  /**
   * 接口中也有可以方法的实现(是不是惊呆了!)
   * @return
   */
  def test = {
    println("hello")
  }
}


class Bird(var name: String) extends Flyable {
  /**
   * 实现接口中的方法
   */
  def fly: Unit = {
    println("I am a " + name + ", and I can fly~")
  }

  override def toString = {
    "this is a Bird:" + name
  }
}

object Bird {
  def apply(name: String) = {
    new Bird(name)
  }

}

 从上面的代码中,可以看出trait与java中interface的异同,相同的是如果把trait单纯当接口来用,trait中只需要定义方法签名即可,然后由"子类"来实现。不同的是,scala中的trait里也可以有方法实现!而且实现接口时,关键字不是implements而是extends(当然,还可能是with,后面还会提到),这说明scala中trait并不仅仅只是接口,它也是一种特殊的类。

trait的mixin:

trait还有一个神奇的特性,可以在运行时,动态与其它类合体!见下面的代码:

package yjmyzz


object App {

  def main(args: Array[String]) {
    val duck = new Bird("duck") with Swim
    println(duck.isInstanceOf[Flyable]) //true
    println(duck.isInstanceOf[Swim]) //true 注意这里:表示此时Bird也是一个Swim实例
    duck.fly //I am a duck, and I can fly~
    duck.swim //I can swim! 注:是不是很有意思,绝对的动态晚绑定!
  }
}

/**
 * 定义一个"接口"
 */
trait Flyable {

  /**
   * 定义接口方法
   */
  def fly;


  /**
   * 接口中也有可以方法的实现(是不是惊呆了!)
   * @return
   */
  def test = {
    println("hello")
  }
}


/**
 * 再来一个"接口"
 */
trait Swim {
  def swim = {
    println("I can swim!")
  }
}


class Bird(var name: String) extends Flyable {

  /**
   * 实现接口中的方法
   */
  def fly: Unit = {
    println("I am a " + name + ", and I can fly~")
  }

  override def toString = {
    "this is a Bird:" + name
  }
}

我们又新增了一个trait:Swim,然后注意第7行,通过with Swim,硬是把跟Swim毫不相关的Bird实例跟它搅在一起了,然后实例duck就获得了Swim的能力! 这种场景下,trait就不应该理解为接口,而应该认为它是一种特性,是一种可以动态赋予其它实例的超能力!(这也是为什么关键字不叫interface,而是叫trait的原因吧)

 

to be continued...

scala 学习笔记(04) OOP(中)

标签:

原文地址:http://www.cnblogs.com/yjmyzz/p/4719256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!