国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

詳細介紹Scala面向對象編程

開發 開發工具
本文介紹了Scala編程語言的面向對象編程,可以說介紹的很詳細。希望對大家有幫助,一起來看。

Scala編程語言近來抓住了很多開發者的眼球。Scala 和Java, Python, Ruby, Smalltalk 以及其它類似語言一樣,是一種面向對象語言。如果你來自Java 的世界,你會發現對Java 對象模型限制的一些顯著改進。

類和對象的基礎

讓我們來回顧一下Scala OOP 的術語。

注意

我們在前面看到Scala 有聲明對象的概念,我們會在“類和對象:狀態哪里去了?”章節來討論它們。我們會使用術語實例來稱呼一個類的實例,意思是類的對象或者實例,用來避免兩者之間的混淆。

類可以用關鍵字class 來聲明。我們會在后面看到也可以加上一些其它的關鍵字,例如用final 來防止創建繼承類,以及用abstract 表示這個類不能被實例化,這通常是因為它包含或者繼承了沒有具體定義的成員聲明。

一個實例可以用this 關鍵字來引用自己,這一點和Java 及其類似語言一樣。

遵循Scala 的約定,我們使用術語方法(method)來指代實例的函數(function)。有一些面向對象語言使用術語成員函數(member function)。方法定義由def 關鍵字開始。

和Java 一樣,但是和Ruby,Python 有所區別,Scala 允許重載方法。兩個或以上的方法可以有同樣的名字,只要它們的完整簽名是唯一的。簽名包含了類型名字,參數列表及其類型,以及方法的返回值。

不過,這里有一個由類型消除引起的例外,這是一個JVM 的特性,但是被Scala 在JVM 和.NET 平臺上所利用從而最小化兼容問題。假設兩個方法其它方面都一樣,只是其中一個接受List[String] 參數,而另外一個接受List[Int] 參數,如下所示。

 

  1. // code-examples/BasicOOP/type-erasure-wont-compile.scala   
  2. // WON'T COMPILE   
  3. object Foo {   
  4. def bar(list: List[String]) = list.toString   
  5. def bar(list: List[Int]) = list.size.toString   
  6. }   

 

你會在第二個方法處得到一個編譯錯誤,因為這兩個方法在類型消除后擁有一樣的簽名。

警告

Scala 解釋器會讓你輸入這兩個方法。它簡單地拋棄了***個版本。然而,如果你嘗試用:load 文件命令去加載上面的那個例子,你會得到一樣的錯誤。

同樣是約定,我們使用術語字段(field)來指代實例的變量。其它語言則通常使用術語屬性(attribute),例如Ruby。注意,一個實例的狀態就是該實例的字段所呈現的值的聯合。

正如我們所說的,只讀的(“值”)字段用val 關鍵字來聲明,可讀寫字段則用var 關鍵字來聲明。

Scala 也是允許在類中聲明類型

我們一般使用術語成員(member)來指代字段,方法或者類型。注意,字段和方法成員(除開類型成員)共享一樣的名稱空間,這一點和Java 不一樣。

***,引用類型的實例可以用new 關鍵字創建,和Java,C# 一樣。注意,你在使用默認構造函數時可以不用寫括號(例如,沒有參數的構造函數)。你某些情況下,字面值可以被用來替代new。例如val name = "Programming Scala" 等效于val name = new String("Programming Scala")。

值類型的實例(例如Int,Double 等),和Java 這樣的語言中的元類型相對應,永遠都用字面值來創建。例如1,3.14 等。實際上,這些類型沒有公有構造函數,所以像val i = new Int(1) 這樣的表達式是不能編譯的。

我們會在“Scala 類型結構”章節討論引用類型和值類型的區別。

父類

Scala 支持單繼承,不支持多繼承。一個子(或繼承的)類只可以有一個父類(基類)。唯一的例外是Scala 類層級結構中的根,Any,沒有父類。

我們已經見過幾個父類和子類的例子了。來看下面的例子:

 

  1. // code-examples/TypeLessDoMore/abstract-types-script.scala   
  2. import java.io._   
  3. abstract class BulkReader {   
  4. // ...   
  5. }   
  6. class StringBulkReader(val source: String) extends BulkReader {   
  7. // ...   
  8. }   
  9. class FileBulkReader(val source: File) extends BulkReader {   
  10. // ...   
  11. }  

 

和在Java 一樣,關鍵字extends 指明了父類,在這里就是BulkReader。在Scala 中,extends 也會在一個類把一個trait 作為父親繼承的時候使用(即使當它用with 關鍵字混入其它traits 的時候也是一樣)。而且,extends 也在一個trait 是另外一個trait 或類的繼承者的時候使用。是的,traits 可以繼承自類。

如果你不繼承任何父類,默認的父親是AnyRef,Any 的一個直接子類

#p#

Scala 構造函數

Scala 可以區分主構造函數和0個或多個輔助構造函數。在Scala 里,類的整個主體就是主構造函數。構造函數所需要的任何參數被列于類名之后。我們已經看到過很多例子了,來看下面的例子。

 

  1. // code-examples/Traits/ui/button-callbacks.scala   
  2. package ui   
  3. class ButtonWithCallbacks(val label: String,   
  4. val clickedCallbacks: List[() => Unit]) extends Widget {   
  5. require(clickedCallbacks != null"Callback list can't be null!")   
  6. def this(label: String, clickedCallback: () => Unit) =   
  7. this(label, List(clickedCallback))   
  8. def this(label: String) = {   
  9. this(label, Nil)   
  10. println("Warning: button has no click callbacks!")   
  11. }   
  12. def click() = {   
  13. // ... logic to give the appearance of clicking a physical button ...   
  14. clickedCallbacks.foreach(f => f())   
  15. }   
  16. }  

 

類ButtonWithCallbacks 表示了圖形用戶界面上的一個按鈕。它有一個標簽和一個回調函數的列表,這些函數會在按鈕被點擊的時候被調用。每一個回調函數都不接受參數,并且返回Unit。方法click 會遍歷回調函數的列表,然后一個個地調用它們。

ButtonWithCallbacks 定義了3個構造函數。主構造函數,類的主題,有一個參數列表來接受標簽字符串和回調函數的列表。因為每一個參數都被聲明為val, 編譯器為每一個參數都生成一個私有字段(會使用一個不同的內部名稱),以及名字和參數一致的公有讀取方法。“私有”和“公有”在這里的意思和在大多數面向對象語言里一樣。我們會在下面的“可見性規則”章節討論不同的可見性規則和控制它們的關鍵字。

如果參數有一個var 關鍵字,一個公有的寫方法會被自動生成,并且名字為參數名加下劃線等號(_=)。例如,如果label 被聲明為var, 對應的寫方法則為label_=,而且它會接受一個字符串作為參數。

有時候你可能不希望自動生成這些訪問器方法。換句話說,你希望字段是私有的。在val 或者var 之前加上private 關鍵字,訪問器方法就不會被生成

注意

對于Java 程序員,Scala 沒有遵循s [JavaBeanSpec] 約定 - 字段讀取、寫方法分別對應get 和set 的前綴,緊接著是***個字母大寫的字段名。我們會在“當方法和字段存取器無法區分時:唯一存取的原則”章節中討論唯一存取原則時看到原因。不過,你可以在需要時通過scala.reflect.BeanProperty 來獲得JavaBeans 風格的訪問器。

當類的一個實例被創建時,每一個參數對應的字段都會被參數自動初始化。初始化這些字段不需要邏輯上的構造函數,這和很多面向對象語言不同。

ButtonWithCallbacks 類主體(換言之,構造函數)的***個指令是一個保證被傳入構造函數的參數列表是一個非空列表的測試。(不過它確實允許一個空的Nil 列表。)它使用了方便的require 函數,這個函數是被自動導入到當前的作用域中的。如果這個列表是null, require 會拋出一個異常。require 函數和它對應的假設對于設計契約式程序非常有用。

這里是ButtonWithCallbacks 的完整Specification(規格)的一部分,它展示了require 指令的作用。

 

  1. // code-examples/Traits/ui/button-callbacks-spec.scala   
  2. package ui   
  3. import org.specs._   
  4. object ButtonWithCallbacksSpec extends Specification {   
  5. "A ButtonWithCallbacks" should {   
  6. // ...   
  7. "not be constructable with a null callback list" in {   
  8. val nullList:List[() => Unit] = null   
  9. val errorMessage =   
  10. "requirement failed: Callback list can't be null!"   
  11. (new ButtonWithCallbacks("button1", nullList)) must throwA(   
  12. new IllegalArgumentException(errorMessage))   
  13. }   
  14. }   
  15. }  

 

Scala 甚至使得把null 作為第二個參數傳給構造函數變得很困難;它不會再編譯時做類型檢查。然而,你向上面那樣可以把null 賦給一個value。如果我們沒有must throwA(...) 子句,我們會看到下面的異常被拋出。

 

  1. java.lang.IllegalArgumentException: requirement failed: Callback list can't be null!   
  2. at scala.Predef$.require(Predef.scala:112)   
  3. at ui.ButtonWithCallbacks.(button-callbacks.scala:7)   
  4. ....  

 

ButtonWithCallbacks 定義了兩個方便用戶使用的輔助構造函數。***個輔助構造函數接受一個標簽和一個單獨的回調函數。它調用主構造函數,并且傳遞給它標簽和包含了回調函數的新列表。

第二個輔助構造函數只接受一個標簽。它調用主構造函數,并且傳入Nil(Nil 表示了一個空的List 對象)。然后構造函數打印出一條警告消息指明沒有回調函數,因為列表是不可變的,所以我們沒有機會用一個新的值來替代現有的回調函數列表。

為了避免無限遞歸,Scala 要求每一個輔助構造函數調用在它之前定義的構造函數[ScalaSpec2009]。被調用的構造函數可以是另外一個輔助構造函數或者主構造函數,而且它必須出現在輔助構造函數主體的***句。額外的過程可以在這個調用之后出現,比如我們例子中的打印出一個警告消息。

注意

因為所有的輔助構造函數最終都會調用主構造函數,它主體中進行的邏輯檢查和其它初始化工作會在所有實例被創建的時候執行。

#p#

Scala 對構造函數的約束有一些好處。

消除重復

因為輔助構造函數會調用主構造函數,潛在的重復構造邏輯就被大大地消除了。

代碼體積的減少

正如例子中所示,當一個或更多的主構造函數參數被聲明為val 或者var,Scala 會自動產生一個字段,合適的存取方法(除非它們被定義為private,私有的),以及實例被創建時的初始化邏輯。

不過,這樣也有至少一個缺點。

缺少彈性

有時候,迫使所有構造函數都是用同一個構造函數體并不方便。然而,我們發現這樣的情況只是極少數。在這種情況下,可能是因為這個類負責了太多東西,而且應該被重構為更小的類。

調用父類構造函數

子類的主構造函數必須調用父類的一個構造函數,無論是主構造函數或者是輔助構造函數。在下面的例子里,類RadioButtonWithCallbacks 會繼承ButtonWithCallbacks,并且調用ButtonWithCallbacks 的主構造函數。“Radio”按鈕可以被設置為開或者關。

 

  1. // code-examples/BasicOOP/ui/radio-button-callbacks.scala   
  2. package ui   
  3. /**   
  4. * Button with two states, on or off, like an old-style,   
  5. * channel-selection button on a radio.   
  6. */   
  7. class RadioButtonWithCallbacks(   
  8. var on: Boolean, label: String, clickedCallbacks: List[() => Unit])   
  9. extends ButtonWithCallbacks(label, clickedCallbacks) {   
  10. def this(on: Boolean, label: String, clickedCallback: () => Unit) =   
  11. this(on, label, List(clickedCallback))   
  12. def this(on: Boolean, label: String) = this(on, label, Nil)   
  13. }  

 

RadioButtonWithCallbacks 的主構造函數接受3個參數,一個開關狀態(真或假),一個標簽,以及一個回調函數例表。它把標簽和回調函數列表傳給父類ButtonWithCallbacks。開關狀態參數(on)被聲明為var,所以是可變的。on 也是每一個單選按鈕的私有屬性。 為了和父類保持統一,RadioButtonWithCallbacks 還定義了兩個輔助構造函數。注意它們必須調用一個之前定義的構造函數,和之前一樣。它們不能直接調用ButtonWithCallbacks 的構造函數。

注意

雖然和Java 一樣,super 關鍵字通常被用來調用重寫的方法,但是它不能被用作調用父類的構造函數。

嵌套類

Scala 和許多面向對象語言一樣,允許你嵌套聲明類。假設我們希望所有的部件都有一系列的屬性。這些屬性可以是大小,顏色,是否可見等。我們可以使用一個簡單的map 來保存這些屬性,但是我們假設還希望能夠控制對這些屬性的存取,并且當它們改變時能進行一些其它的操作。

下面的例子:

 

  1. // code-examples/BasicOOP/ui/widget.scala   
  2. package ui   
  3. abstract class Widget {   
  4. class Properties {   
  5. import scala.collection.immutable.HashMap   
  6. private var values: Map[String, Any] = new HashMap   
  7. def size = values.size   
  8. def get(key: String) = values.get(key)   
  9. def update(key: String, value: Any) = {   
  10. // Do some preprocessing, e.g., filtering.   
  11. valuesvalues = values.update(key, value)   
  12. // Do some postprocessing.   
  13. }   
  14. }   
  15. val properties = new Properties   
  16. }  

 

我們添加了一個Properties 類,包含了一個私有的,可變的HashMap (HashMap 本身不可變)引用。我們同時加入了3個公有方法來獲取大小(例如,定義的屬性個數),獲取map 中的元素,以及更新map 中對應的元素等。我們可能需要在update 方法上做更多的工作,已經用注釋標明。

注意

你可以從上面的例子中看到, 允許在一個類中定義另外一個,或者成為“嵌套”。當你有足夠多的功能需要歸并到一個類里,并且這個類在僅會被外層類所使用時,一個嵌套類就非常有用。

到這里為止,我們學習了如何聲明一個類,如何初始化它們,以及繼承的一些基礎。希望對你有幫助。

【編輯推薦】

  1. Scala編程指南 更少的字更多的事
  2. Scala是給優秀程序員準備的
  3. 簡單介紹Java EE容器
  4. 詳細介紹JAVA和C++區別
  5. 談java web server與io形式
責任編輯:于鐵 來源: 互聯網
相關推薦

2010-11-17 11:31:22

Scala基礎面向對象Scala

2011-07-05 16:15:49

面向對象

2009-06-16 17:09:17

Scala面向對象函數編程

2009-07-08 16:10:24

Scala簡介面向對象函數式

2017-04-21 09:07:39

JavaScript對象編程

2012-01-17 09:34:52

JavaScript

2009-09-09 11:14:16

Scala對象

2011-07-21 17:19:47

java面向對象

2010-03-11 10:34:22

Scala

2022-07-30 23:41:53

面向過程面向對象面向協議編程

2012-12-13 11:01:42

IBMdW

2012-02-27 09:30:22

JavaScript

2009-10-13 17:03:55

VB.NET面向對象

2011-05-25 10:21:44

Javascript

2023-01-10 09:06:17

2010-07-16 17:23:57

Perl面向對象編程

2023-12-11 15:32:30

面向對象編程OOPpython

2010-07-13 17:18:29

Perl面向對象編程

2012-12-18 09:24:47

2019-03-26 10:50:22

Python面向對象編程語言
點贊
收藏

51CTO技術棧公眾號

国产裸舞福利在线视频合集| 国产精品4hu.www| 国产不卡在线一区| 欧美成人激情在线| 日本在线视频1区| 成人av免费观看| 国内外成人免费视频| 亚洲日本中文| 91精品国产色综合久久| 亚洲国产日韩欧美在线观看| 欧美亚洲一区| 国产美女扒开尿口久久久| 不卡一二三区| 欧美日本国产视频| 一本大道香蕉久在线播放29 | 91色视频在线观看| 日韩三区四区| 欧美成人精品1314www| 一本色道久久加勒比88综合| 成人高清在线视频| 日韩欧美亚洲日产国产| 国内在线观看一区二区三区| 国产精品免费一区| 亚洲精品**不卡在线播he| 亚洲美女动态图120秒| 国产色在线观看| 精品国产乱码久久久久久虫虫漫画| 免费观看成人网| 国产成人精品一区二| 中文字幕人成一区| 久久久久国产精品午夜一区| 成人在线激情视频| 国产伦一区二区三区| 欧美成人手机在线| 欧美成人黑人| 日韩一卡二卡三卡国产欧美| 国产视频精选在线| 亚洲成av人片在线观看| 激情四房婷婷| 一区二区三区四区不卡视频| 天天操,天天操| 91老司机福利 在线| 99热一区二区三区| 奇米色一区二区三区四区| 免费久久99精品国产自| 老鸭窝亚洲一区二区三区| 农村寡妇一区二区三区| 亚洲精品男同| 国模一区二区三区私拍视频| 国产精品呻吟| 色噜噜狠狠一区二区三区| 麻豆一区二区在线| 亚洲欧美成人一区| 国产精品亚洲а∨天堂免在线| 日韩精品免费一区| 99精品热视频| 久草在在线视频| 一区二区三区在线观看视频| 中文在线а天堂av| 色嗨嗨av一区二区三区| 成人在线网址| 国产亚洲精品一区二555| 白嫩亚洲一区二区三区| 久久久精品免费| 少妇一区二区三区| 亚洲aaaaaa| 蜜臀99久久精品久久久久久软件| 亚洲精品免费在线看| 国产一区二区久久| 欧美日韩亚洲第一| 午夜电影一区二区| a级网站在线播放| 亚洲电影在线观看| 国产精品777777在线播放| 国产精品激情av在线播放| 国产精品久久久久久模特| 一区视频二区视频| 国产精品日韩精品欧美在线| 欧洲成人av| 亚洲人精品午夜在线观看| 免费看成人人体视频| 成人免费大片黄在线播放| 日韩有码一区二区三区| 青青草原成人网| 狠狠躁夜夜躁久久躁别揉| 在线三级中文| 久久久久久久久亚洲| 欧美日韩国产一区精品一区| 日本在线视频www色| 中文字幕一区免费在线观看| 偷拍自拍在线视频| 中文字幕欧美国内| 久久中文字幕二区| 久久人妻无码一区二区| 亚洲视频一区二区在线| 视频在线这里都是精品| 97在线免费观看| 国内精品美女在线观看| 欧美a在线视频| 欧美日韩亚洲精品内裤| 在线观看v片| 国产精品久久视频| 美女在线视频一区| 色久视频在线观看| 国产亚洲视频在线| 欧美三级乱码| 少妇人妻互换不带套| 欧美一级国产精品| 欧美日韩高清| 青青青青草视频| 宅男噜噜噜66一区二区66| 亚洲国产网址| 欧美激情亚洲天堂| 欧美美女bb生活片| 四虎884aa成人精品最新| 一本一道久久a久久精品综合 | 91麻豆精品一区二区三区| 精品视频三区| 欧美黑人视频一区| 国内国产精品久久| 国产h在线观看| 欧美尺度大的性做爰视频| 免费亚洲一区| 麻豆传媒在线播放| 中文亚洲视频在线| 久久综合九色| 亚洲kkk444kkk在线观看| 久久久久久这里只有精品| 国产一区二区女| 成人在线免费观看| 国产精品爽爽爽爽爽爽在线观看| 99精品欧美一区二区三区小说 | 中文字幕日韩在线观看| 亚洲精品一区二区在线看| 少妇高清精品毛片在线视频| 精品国产一区二区三区久久久蜜月 | 国产欧美高清在线| 精品剧情v国产在线观看在线| 欧美超碰在线| 成人黄色电影网址| 正在播放欧美视频| 美女任你摸久久| jvid福利写真一区二区三区| 免费精品国产的网站免费观看| 国产主播在线看| 日本在线视频www鲁啊鲁| 久久精品国产99精品国产亚洲性色| 国产午夜精品视频| 久久在线观看免费| 色天天综合久久久久综合片| 九九视频精品免费| 亚洲精品18| 国产无套粉嫩白浆在线2022年 | 91精品国产综合久久久蜜臀粉嫩| 国产精品天天看天天狠| 屁屁影院ccyy国产第一页| 欧美无砖砖区免费| 亚洲一区二区| 新版中文字幕在线资源| 青青精品视频播放| 国产精品久久久久久妇女6080| 男人天堂久久| 欧美 日韩 国产在线观看| 俺去了亚洲欧美日韩| 不卡的av在线播放| 日韩欧美一区二区三区在线观看| 一本色道久久88亚洲精品综合| 欧美videos大乳护士334| 日韩电影在线观看一区| 18加网站在线| 美女黄色片网站| 亚洲男女性事视频| 成人妖精视频yjsp地址| 久久亚洲精品中文字幕| 国产真实乱子伦| 欧美一区二区三区艳史| 亚洲男人的天堂av| 最新国产精品| www国产在线观看 | 精品久久中文字幕久久av| 日韩精品二区| 永久免费av在线| 中文字幕日韩精品一区二区| 一本色道久久88精品综合| 欧美韩日一区二区三区四区| 精品久久久久中文字幕小说 | jlzzjlzz亚洲日本少妇| 欧美日韩va| 一道本在线免费视频| 国产精品视频网| 欧美日韩精品系列| 国产高清成人在线| 同性恋视频一区| 成人免费黄色网页| www插插插无码免费视频网站| 蜜臀久久99精品久久久无需会员| 亚洲免费av观看| 久久欧美肥婆一二区| 亚洲精品69| 少妇免费视频|