1. 程式人生 > 實用技巧 >Scala(八)【面向物件總結】

Scala(八)【面向物件總結】

面向物件總結

面向物件
	1、scala包
		1、宣告包
			1、在檔案第一行通過package 包名
			2、package 包名{
				....
			}
			第二種方法,包名只能在target目錄才能看到
		2、匯入包
			1、匯入包下所有類: import 包名._
			2、匯入包下多個類: import 包名.{類名1,類名2,..}
			3、匯入包下除開個別類的所有型別: import 包名.{不匯入的類名=>_,_}
			4、給類起別名: import 包名.{類名=>別名}
		3、包物件
			1、語法: package object 包名
			包物件中定義變數、方法、函式在包中任何地方都可以使用
	2、類和物件
		1、類
			1、語法: class 類名
			2、定義屬性:
				class 類名{
					val/var 變數:變數型別 = 值
					//var定義的變數可以通過_賦予初始值:null、0、false、0.0
				}
			3、定義方法: 與之前定義方法的語法一樣
		2、物件: new 類名
		3、構造器
			1、主構造器: 列名後面的()代表主構造器。在主構造器中可以定義成員屬性
				class 類名(val 屬性名:型別[= 預設值],var 屬性名:型別 [= 預設值], 屬性名:型別[=預設值])
					在主構造器中定義屬性的時候:val\var\不帶val、var的區別:
						val:不可修改,有預設的get方法
						var:可以修改,有預設的get\set方法
						不帶val、var: 只能在類中使用。而且如果該屬性沒有在class中使用,相當於沒有。如果使用,則會生成一個private的屬性。只是這個屬性沒有get/set方法
			2、輔助構造器:
				1、語法: def this(引數名:引數型別,...) = {
					//第一行呼叫其他的輔助構造器或者主構造器
				}
				輔助構造器可以過載
		4、構造器引數:
			1、主構造器中屬性可以給預設值
			2、在建立物件的時候,可以通過帶名引數來指定將值賦給哪個屬性
		5、封裝:  *****
			為了相容java,生成java的get/set方法。
			只需要在屬性名上面添加註解:@BeanProperty。
		6、繼承: 語法和java一樣,都是通過extends關鍵字實現繼承
			哪些不能夠被繼承:
				1、final修飾的class不能被繼承
				2、private修飾的成員變數、成員方法不可被繼承
			哪些不能夠被重寫
				1、final修飾的val定義的屬性不可用被重寫
				2、var修飾的屬性不可以被重寫
			重寫: 通過override關鍵字標識方法/屬性被重寫
		7、多型:
			1、java中多型是表現在方法上
			2、scala中方法和屬性都會多型
		8、抽象類: 通過abstract關鍵字標識類為抽象類
			1、抽象類中既可以定義抽象方法[沒有方法體]也可以定義具體方法
			2、抽象類中既可以定義抽象屬性[沒有賦初始值的屬性]也可以定義具體屬性
			3、匿名子類:
				new 抽象類{
					//實現抽象類的抽象方法和抽象屬性
				}
		9、伴生類和伴生物件
			需要滿足兩個條件:
				1、class名和object名一樣
				2、class與object在同一個原始檔中
				class稱之為伴生類,object伴生物件
				伴生類和伴生物件相互之間可以呼叫對方的私有屬性或者方法
			apply方法: 
				apply方法定義在伴生物件中
				使用來簡化伴生類例項的建立
				
				def apply(變數名:變數型別,..) = new 伴生類(變數名,..)
			有了apply方法之後,後續建立伴生類例項的時候就可以通過以下方式建立:
				1、類名.apply(值,..)
				2、類名(值,...)
				上面兩種形式是完全等價
		10、特質
			1、定義語法: trait 特質名{...}
			2、scala中是單繼承,多混入
			3、特質和抽象類很像,都是既可以定義抽象方法也可以定義具體的方法
									既可以定義抽象屬性也可以定義具體的屬性
			4、如何混入特質?
				1、如果子類需要繼承父類,先通過extends關鍵字繼承父類,後面通過with關鍵字混入特質
				2、如果子類不需要繼承父類,第一個特質通過extends關鍵字混入,其他的特質通過with關鍵字混入
			5、子類混入多個特質,這多個特質中都是同名的方法,如何處理?
				1、如果這多個特質沒有關係[沒有相同的父類/父特質]: 
					直接重寫同名方法。如果重寫之後,在方法體中需要呼叫父特質同名的方法。只會呼叫最後一個特質的同名方法
				2、如果這多個特質有關係[屬於同一個父特質]
					直接重寫同名方法。如果重寫之後,在方法體中需要呼叫父特質同名的方法。根據混入的順序,從右往左開始呼叫,共同父特質的同名方法最後才呼叫
					class A extends B with C with D{
						overirde def m1() = {
							println("...")
							super.m1()
						}
					}
					B、C、D繼承AA
					A[m1]->D[m1]->C[m1]->B[m1]->AA[m1]
			6、物件混入:
				語法: new 物件 with 特質名
				通過物件混入,可以實現將某些物件有特質的特徵[屬性/方法/函式]
			7、特質的自身型別:
				語法:  
					trait 特質名{
						this:型別=>  //子類要想混入當前的特質,必須繼承/混入指定的class/trait
					}
		11、擴充套件
			1、型別檢查、轉換  *****
				物件.isInstanceOf[型別] : 用來判斷物件是否屬於某個型別
				物件.asInstanceOf[型別]: 用來將物件轉為指定的型別
				物件.getClass: 獲取物件的class形式
				classOf[類名]: 獲取類的class形式
			2、列舉類、應用類:
				列舉類: 繼承 Enumeration 
				應用類: 繼承 App
					繼承App之後,就可以不用寫main方法。在object中的程式碼就是相當於寫在main方法裡面
			3、type定義新型別: 給類起別名
				type s = String
				val name:s = "xxx"