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

鍍金池/ 教程/ Scala/ 組合和繼承–定義 factory 對象
包對象
Ordered Trait
組合和繼承–定義 final 成員
基本數(shù)據(jù)類型
Match 表達(dá)式
類和對象 (三)
操作基本數(shù)據(jù)類型
for 表達(dá)式
組合和繼承–重載成員函數(shù)和方法
類和對象 (二)
組合和繼承–定義 factory 對象
組合和繼承–多態(tài)和動態(tài)綁定
Trait 的基本概念
if 表達(dá)式
組合和繼承–抽象類
函數(shù)–函數(shù)字面量的一些簡化寫法
while 循環(huán)
組合和繼承–使用組合還是繼承?
訪問控制修飾符
Trait 示例–Rectangular 對象
組合和繼承–定義參數(shù)化成員變量
組合和繼承–定義無參數(shù)方法
類和對象 (一)
函數(shù)–閉包
函數(shù)–類成員函數(shù)
Scala 基本數(shù)據(jù)類型的實現(xiàn)方法
try 表達(dá)式處理異常
選擇瘦接口還是胖接口設(shè)計?
組合和繼承–小結(jié)
創(chuàng)建新的控制結(jié)構(gòu)
使用 import
為訪問控制修飾符添加作用域
Scala 的類層次關(guān)系
類和對象 (五)
傳名參數(shù)
柯里化函數(shù)
函數(shù)–頭等公民
組合和組合和繼承–定義 heighten 和 widen 函數(shù)
使用 Package–將代碼放入包中
隱含的 import
所有類的公共子類–底層類型
進一步 Scala
函數(shù)–局部函數(shù)
引用包中的代碼
組合和繼承–使用 override 修飾符
組合和繼承–實現(xiàn)類 Element 的 above,beside 和 toString()方法
類和對象 (四)
函數(shù)–尾遞歸
沒有“break”和“continue”的日子
組合和繼承–調(diào)用基類構(gòu)造函數(shù)
減低代碼重復(fù)
函數(shù)–函數(shù)–可變參數(shù),命名參數(shù),缺省參數(shù)
起步 Scala
組合和繼承–擴展類
函數(shù)–部分應(yīng)用的函數(shù)
開始神奇的 Scala編程之旅
組合和繼承–概述
Trait 用來實現(xiàn)可疊加的修改操作

組合和繼承–定義 factory 對象

到目前為止,我們定義了關(guān)于布局元素類的一個層次結(jié)構(gòu)。你可以把包含這個層次關(guān)系的類作為 API 接口提供給其它應(yīng)用,但有時你可以希望對函數(shù)庫的用戶隱藏這種層次關(guān)系,這通??梢允褂?factory(構(gòu)造工廠)對象來實現(xiàn)。一個 factory 對象定義了用來構(gòu)造其它對象的函數(shù)。庫函數(shù)的用戶可以通過工廠對象來構(gòu)造新對象,而不需要通過類的構(gòu)造函數(shù)來創(chuàng)建類的實例。使用工廠對象的好處是,可以統(tǒng)一創(chuàng)建對象的接口并且隱藏被創(chuàng)建對象具體是如何來表示的。這種隱藏可以使得你創(chuàng)建的函數(shù)庫使用變得更簡單和易于理解,也正是隱藏部分實現(xiàn)細(xì)節(jié),可以使你有機會修改庫的實現(xiàn)而不至于影響庫的接口。

實現(xiàn) factory 對象的一個基本方法是采用 singleton 模式,在 Scala 中,可以使用類的伴隨對象(companion 對象)來實現(xiàn)。比如:

object Element {
  def elem(contents: Array[String]):Element =
   new ArrayElement(contents)
  def elem(chr:Char, width:Int, height:Int) :Element =
    new UniformElement(chr,width,height)
  def elem(line:String) :Element =
    new LineElement(line)
}

我們先把之前 Element 的實現(xiàn)列在這里:

abstract class Element {
  def contents: Array[String]
  def height: Int = contents.length
  def width: Int = if (height == 0) 0 else contents(0).length
  def above(that: Element) :Element =
    new ArrayElement(this.contents ++ that.contents)
  def beside(that: Element) :Element = {
    new ArrayElement(
      for(
        (line1,line2) <- this.contents zip that.contents
      ) yield line1+line2
    )
  }
  override def toString = contents mkString "\n"
}

有了 object Element(類 Element 的伴隨對象),我們可以利用 Element 對象提供的 factory 方法,重新實現(xiàn)類 Element 的一些方法:

abstract class Element {
  def contents: Array[String]
  def height: Int = contents.length
  def width: Int = if (height == 0) 0 else contents(0).length
  def above(that: Element) :Element =
    Element.elem(this.contents ++ that.contents)
  def beside(that: Element) :Element = {
    Element.elem(
      for( 
        (line1,line2) <- this.contents zip that.contents
      ) yield line1+line2
    ) 
  }
  override def toString = contents mkString "\n"
}

這里我們重寫了 above 和 beside 方法,使用伴隨對象的 factory 方法 Element.elem 替代 new 構(gòu)造函數(shù)。

這樣修改之后,庫函數(shù)的用戶不要了解 Element 的繼承關(guān)系,甚至不需要知道類 ArrayElement,LineElement 定義的存在,為了避免用戶直接使用 ArrayElement 或 LineElement 的構(gòu)造函數(shù)來構(gòu)造類的實例,因此我們可以把 ArrayElement,UniformElement 和 LineElement 定義為私有,定義私有可以也可以把它們定義在類 Element 內(nèi)部(嵌套類)。下面為這種方法的使用:

object Element {
  private class ArrayElement(val contents: Array[String])
    extends Element {
  }
  private class LineElement(s:String) extends ArrayElement(Array(s)) {
    override def width = s.length
    override def height = 1
  }
  private class UniformElement (ch :Char,
    override val width:Int,
    override val height:Int
  ) extends Element{
    private val line=ch.toString * width
    def contents = Array.fill(height)(line)
  }
  def elem(contents: Array[String]):Element =
   new ArrayElement(contents)
  def elem(chr:Char, width:Int, height:Int) :Element =
    new UniformElement(chr,width,height)
  def elem(line:String) :Element =
    new LineElement(line)
}