2011-08-05 64 views
6

我有以下代碼:是否可以鏈接不同特徵的方法?

class Parameterizable{ 
    var map: Map[String, String] = new scala.collection.immutable.HashMap() 
    def put(entry: Tuple2[String, String]) = { 
    map = map + entry; this 
    } 
} 

class Query() extends Parameterizable{ 
    override def toString = { 
    map.isEmpty match{ 
     case true => "" 
     case false => "?" + map.map{case (key, value) => key + "=" + value}.mkString("&") 
    } 
    } 
} 

trait PageParameter extends Parameterizable{ 
    def page(page: Int) = put(("page" -> page.toString)) 
    def pageSize(pageSize: Int) = put(("pagesize" -> pageSize.toString)) 
} 

trait DateParameter extends Parameterizable{ 
    def fromDate(date: java.util.Date) = put(("fromdate" -> (date.getTime()/1000L).toString())) 
    def toDate(date: java.util.Date) = put(("todate" -> (date.getTime()/1000L).toString())) 
} 
//and other similar traits 

我想這樣做:

class ExtendedQuery extends Query with PageParameter with DateParameter 
val query = new ExtendedQuery 
query.page(4).pageSize(5).fromDate(new java.util.Date) 

或:

query.and().page(4).and().pageSize(5).and().fromDate(new java.util.Date) 

是否有可能在Scala呢?

回答

11

可以聲明方法爲返回this.type,然後從他們返回this

trait PageParameter extends Parameterizable{ 
    def page(page: Int) : this.type = { put(("page" -> page.toString)); this } 
    def pageSize(pageSize: Int): this.type = { put(("pagesize" -> pageSize.toString)); this } 
} 

在使用現場,因爲你想,你就可以鏈的電話。看到這個例子:

scala> trait Wibble { 
| def foo : this.type = { println("foo"); this } 
| } 
defined trait Wibble 

scala> trait Wobble extends Wibble { 
| def bar: this.type = { println("bar"); this } 
| } 
defined trait Wobble 

scala> trait Wubble extends Wibble { 
| def baz: this.type = { println("baz"); this } 
| } 
defined trait Wubble 

現在我可以測試它

scala> new Wibble with Wobble with Wubble 
res0: java.lang.Object with Wibble with Wobble with Wubble = [email protected] 

scala> res0.bar.baz.foo 
bar 
baz 
foo 
res1: res0.type = [email protected] 
相關問題