自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Scala程序中的擴(kuò)展類(lèi)

開(kāi)發(fā) 后端
本文節(jié)選自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻譯的《Programming in Scala》的第十章。Scala是一種針對(duì) JVM 將函數(shù)和面向?qū)ο蠹夹g(shù)組合在一起的編程語(yǔ)言。

我們?nèi)匀恍枰軌騽?chuàng)建新的元素對(duì)象。你已經(jīng)看到了因?yàn)轭?lèi)Element是抽象的,所以“new Element”不能被用來(lái)做這件事。因此,為了實(shí)例化一個(gè)元素,我們需要?jiǎng)?chuàng)建擴(kuò)展了Element并實(shí)現(xiàn)抽象的contents方法的子類(lèi)。代碼10.3展示了一種可能的方式:

  1. class ArrayElement(conts: Array[String]) extends Element {  
  2.  def contents: Array[String] = conts  
  3. }  

代碼 10.3 定義ArrayElement為Element的子類(lèi)

51CTO編輯推薦:Scala編程語(yǔ)言專(zhuān)題

類(lèi)ArrayElement定義為擴(kuò)展了類(lèi)Element。就好象Java里,你在類(lèi)名之后使用extends子句那樣:

  1. ... extends Element ... 
這種extends子句有兩個(gè)效果:使類(lèi)ArrayElement從類(lèi)Element繼承所有非私有的成員,并且使ArrayElement成為Element的子類(lèi)型。由于ArrayElement擴(kuò)展了Element,類(lèi)ArrayElement被稱(chēng)為類(lèi)Element的子類(lèi)。反過(guò)來(lái),Element是ArrayElement的超類(lèi)。

如果你省略extends子句,Scala編譯器隱式地假設(shè)你的類(lèi)擴(kuò)展自scala.AnyRef,在Java平臺(tái)上與java.lang.Object一致。因此,類(lèi)Element隱式地?cái)U(kuò)展了類(lèi)AnyRef。你可以在圖釋10.1上看到這些繼承關(guān)系。

 ArrayElement的類(lèi)關(guān)系圖

圖釋 10.1 ArrayElement的類(lèi)關(guān)系圖

繼承:inheritance表示超類(lèi)的所有成員也是子類(lèi)的成員,除了以下兩點(diǎn)。首先,超類(lèi)的私有成員不被子類(lèi)繼承。其次,在子類(lèi)中實(shí)現(xiàn)的與超類(lèi)中的成員具有相同名稱(chēng)和參數(shù)的將不被繼承到子類(lèi)中。這種情況我們說(shuō)子類(lèi)的成員重載:override了超類(lèi)的成員。如果子類(lèi)中的成員是具體的而超類(lèi)中的是抽象的,我們還可以說(shuō)具體的成員實(shí)現(xiàn):implement了抽象的。

例如,ArrayElement的contents方法重載(或者可說(shuō)成:實(shí)現(xiàn))了類(lèi)Element的抽象方法contents。這個(gè)設(shè)計(jì)的一個(gè)漏洞是因?yàn)榉祷財(cái)?shù)組是可變的,所以客戶(hù)端能改變它。本書(shū)中我們希望事情盡量簡(jiǎn)化,但當(dāng)ArrayElement是真實(shí)項(xiàng)目中的部分時(shí),你應(yīng)當(dāng)考慮代之以返回一個(gè)數(shù)組的防御性拷貝。另一個(gè)問(wèn)題是我們現(xiàn)在并不確信contents數(shù)組所有的String元素具有同樣的長(zhǎng)度。這可以通過(guò)在主構(gòu)造器中檢查前提條件,并且一旦違反則拋出異常的方式來(lái)解決。相對(duì)的,類(lèi)ArrayElement從類(lèi)Element繼承了width和height方法。例如,給定ArrayElement的一個(gè)對(duì)象ae,你可以使用ae.width查詢(xún)其長(zhǎng)度,就好象width是定義在類(lèi)ArrayElement中一樣:

  1. scala> val ae = new ArrayElement(Array("hello""world"))  
  2. ae: ArrayElement = ArrayElement@d94e60 
  3. scala> ae.width  
  4. res1: Int = 5 
子類(lèi)型化:subtyping是指子類(lèi)的值可以被用在需要其超類(lèi)的值的任何地方。例如:

  1. val e: Element = new ArrayElement(Array("hello")) 
變量e被定義為類(lèi)型Element,所以其初始化的值也應(yīng)當(dāng)是Element。實(shí)際上,初始化值的類(lèi)型是ArrayElement。這也沒(méi)問(wèn)題,因?yàn)轭?lèi)ArrayElement擴(kuò)展了類(lèi)Element,并且因此,類(lèi)型ArrayElement適用于類(lèi)型Element。想了解更多子類(lèi)和子類(lèi)型之間的差異,參見(jiàn)詞匯表中的subtype。

圖釋10.1還展示了存在于ArrayElement和Array[String]之間的組合:composition關(guān)系。這種關(guān)系被稱(chēng)為組合的原因是由于類(lèi)ArrayElement是被Array[String]“組合”出來(lái)的。因此Scala編譯器將在它為ArrayElement產(chǎn)生的二進(jìn)制類(lèi)中安置一個(gè)字段用來(lái)保留傳入的conts數(shù)組的引用。我們將在本章后續(xù)內(nèi)容中討論一些關(guān)于組合和繼承的設(shè)計(jì)理念,詳見(jiàn)10.11節(jié)。

【相關(guān)閱讀】

  1. 在Scala中定義無(wú)參數(shù)方法
  2. 學(xué)習(xí)Scala的二維布局庫(kù)和抽象類(lèi)
  3. Scala學(xué)習(xí):叫名參數(shù)by-name parameter
  4. Scala:如何編寫(xiě)新的控制結(jié)構(gòu)
  5. Scala學(xué)習(xí):Curry化的函數(shù)

責(zé)任編輯:book05 來(lái)源: Artima
相關(guān)推薦

2009-07-08 15:35:18

Case類(lèi)Scala

2009-09-28 11:37:03

Journal.scaKestrel

2009-07-21 11:25:03

ScalaRational類(lèi)

2009-07-20 18:03:26

Scala程序Singleton對(duì)象

2009-06-16 17:54:38

Scala類(lèi)語(yǔ)法語(yǔ)義

2009-07-22 09:31:59

Scala類(lèi)類(lèi)層級(jí)Java類(lèi)

2009-09-09 11:37:08

Scala的模式匹配

2009-07-22 08:52:05

Scala動(dòng)態(tài)綁定

2009-07-21 08:54:35

Scala富包裝器

2009-07-21 07:30:00

Scala程序Application

2009-07-20 16:56:51

Scala類(lèi)的定義

2009-09-22 10:15:42

PersistentQScala

2009-09-22 09:59:40

QueueCollecScala

2009-07-22 07:45:00

Scala代碼重復(fù)

2009-07-22 09:29:44

ScalaSpiral程序

2009-07-21 17:29:25

Scala第一類(lèi)函數(shù)

2023-06-12 15:33:52

Scalafor循環(huán)語(yǔ)句

2009-12-11 10:42:00

Scala講座類(lèi)定義構(gòu)造函數(shù)

2009-09-22 09:42:24

Scala的核心

2012-11-09 13:44:48

ScalaJVMJava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)