在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Scala/ 信息隱藏
信息隱藏
類型上界
Variance(類型變體)標識
概述和例子說明
類型下界

信息隱藏

上篇的 Queue 的實現(xiàn)在效率上來說還是比較高效的,但是卻給類的使用者暴露一些不必要的實現(xiàn)細節(jié),比如 Queue 的構造函數(shù)使用了兩個 List 對象,其中一個還是個倒序的列表。本篇介紹如何隱藏這些不必要的信息。

在 Java 中,你可以使用私有的構造函數(shù)來隱藏構造函數(shù),在 Scala 中的主構造器缺省包含在類定義中,但你還是可以使用private來修改其訪問屬性。

例如:

class Queue[T] private(
  private val leading:List[T],
  private val trailing:List[T]
 )

在類名和參數(shù)之間的 private 修飾符表明該構造器是私有的,只能在類或其伙伴對象之中使用。而類本身還是可以公開訪問的:

scala> new Queue(List(1,2),List(3))
<console>:9: error: constructor Queue in class Queue cannot be accessed in object $iw
              new Queue(List(1,2),List(3))
              ^

由于主構造器變成私有的,因此我們需要另外的方式來構造 Queue 的實例,一種方法是使用輔助構造器,比如如下的輔助構造函數(shù):

def this() =this(Nil,Nil)
def this(elem: T*) = this (elems.toList,Nil)

注意,參數(shù)類 T* 代表的不定長參數(shù)類型。

另外一種方法是使用 Factory 方法來構造一個隊列。 一個比較簡潔的方法是使用伙伴對象 ,并定義 apply 方法,比如:

object Queue {
   def apply[T](xs: T*) = new Queue[T](xs.toList,Nil)
}

我們使用 apply 定義了構造 Queue 的 factory 方法,因此調(diào)用時可以使用 Queue(1,2,3)的形式來構造一個實例。 Queue(1,2,3)實際為 Queue.apply(1,2,3)調(diào)用,對調(diào)用者來說看起來好像定義了一個可以全局訪問的 factory 構造方法。而其實對于 Scala 來說,所有的方法都必須包含著某個類或?qū)ο笾小?/p>

除了使用私有方法來隱含實現(xiàn)細節(jié)外,還有一種方法可以實現(xiàn)信息的隱藏。我們可以使用 trait 定義類的接口,而把實現(xiàn)細節(jié)全部隱藏起來(使用私有類),代碼實現(xiàn)如下:

trait Queue[T]{
  def head: T
  def tail: Queue[T]
  def enqueue(x:T): Queue[T]
}
object Queue {
  def apply[T](xs: T*):Queue[T] = new QueueImpl[T](xs.toList, Nil)
  private class QueueImpl[T](
        private val leading: List[T],
        private val trailing: List[T]
      ) extends Queue[T]{
    private def mirror =
      if (leading.isEmpty)
        new QueueImpl(trailing.reverse, Nil)
      else
        this
    def head = mirror.leading.head
    def tail = {
      val q = mirror
      new QueueImpl(q.leading.tail, q.trailing)
    }
    def enqueue(x: T) =
      new QueueImpl(leading, x :: trailing)
  }
}

這個實現(xiàn)定義一個 Public 的 Trait 方法,而隱藏了所有的實現(xiàn)細節(jié)。