基本類的使用:(初)數組
1 package com.dtspark.scala.basics 2 /** 3 * trait是一個接口 4 * 接口的第一次繼承用extends,多繼承時用with 5 * 多繼承時,若是這些接口中都有一樣的方法時,則是從右往左的順序執行 6 * 抽象類不能實例化 7 * 類繼承的時候不繼承伴生對象object,只能看見類的接口,而其父類可使用本身伴生對象中的方法 8 * isInstanceOf 和 asInstanceOf的使用 9 * 前者是判斷是否是其子類,後者是進行類型轉換,但必須是父子之間的轉換,不能是徹底不一樣的類 10 */ 11 trait Logger{ 12 def log(message:String){ 13 println("logger "+message) 14 } 15 16 } 17 /** 18 * override 是表示重寫原有方法,(必需要寫) 19 */ 20 trait RichLogger extends Logger{ 21 override def log(message:String){ 22 println("RichLogger:"+message) 23 } 24 } 25 26 class Loggin( name:String)extends Logger{ 27 def loggin{ 28 println("Hi,welcome! "+name) 29 log(name) 30 } 31 32 } 33 34 35 36 trait Information{ 37 38 val information:String //抽象屬性 39 //def getId:String 40 def getInformation:String //抽象方法(不存在方法體) 41 def checkIn:Boolean = { 42 getInformation.equals("Spark") 43 } 44 } 45 46 class Passenger( name:String)extends Information{ 47 //不能夠定義爲val 緣由是由於_的值不明確 48 var id:String=_ //這種方法申明的不是抽象屬性,而是可變屬性,其值爲String的默認值null 49 override val information = name //重寫抽象屬性 50 override def getInformation = information //不執行任何操做,直接給返回值,至關於實現了 51 /** 52 * this關鍵字爲構造方法,重寫構造方法 53 * 副構造函數的第一行必須是構造函數 54 */ 55 def this(name:String,iid:String){ 56 this(name) 57 id=iid; 58 println("hello!!") 59 } 60 def out:String={ 61 name+" : "+id 62 } 63 64 } 65 66 object HelloTrait { 67 def main(args: Array[String]): Unit = { 68 /** 69 * 對象實例化以後又繼承了新的接口,可使用新的方法 70 * 新的接口必須繼承至原有的接口,並重寫新的方法 71 */ 72 val Log = new Loggin("Spark")with RichLogger 73 Log.loggin 74 75 val person = new Passenger("zcb") 76 println(person.out) 77 person.id="123" //不具備封裝性 78 println(person.out) 79 val person1 = new Passenger("zcb1","1234") 80 println(person1.out) 81 val a:Boolean=person.isInstanceOf[Information]//看它是否是其子類 82 println(a) 83 } 84 }
類的繼承和判斷對象是否相等(中)app
1 package com.dtspark.scala.basics 2 /** 3 *class Creature { 4 * val range: Int = 10 5 * val env: Array[Int] = new Array[Int](range) 6 *} 7 8 *class Ant extends Creature { 9 * override val range = 2 10 *} 11 * 在構造時,發生的過程以下: 12 * Ant構造器在構造本身以前,調用超類構造器; 13 * Creature的構造器將range字段設爲10; 14 * Creature的構造器初始化env數組,調用range字段的getter; 15 * range的getter被Ant類重寫了,返回的Ant類中的range,可是Ant類還未初始化,因此返回了0; 16 * env被設置成長度爲0的數組 17 * Ant構造器繼續執行,將range字段設爲2 18 * ------------------------------------------------------------- 19 * 第二種寫法是先初始化sporter的成員,而後在初始化父類的成員,這樣可保證將數據傳給父類,with後面接要繼承的類 20 * class Person10{ 21 * val counter=3 22 * val counterArray =new Array[Int](counter) 23 * } 24 25 * class Sporter extends { 26 * override val counter = 5 27 * }with Person10 28 29 **/這樣初始化後sporter的counterArray的長度爲5 30 class Person10{ 31 val counter=3 32 val counterArray =new Array[Int](counter) 33 } 34 35 class Sporter extends { 36 override val counter = 5 37 }with Person10 38 39 //判斷兩個對象是否相同的方法 40 class Programmer(val name:String,val salary:Double){ 41 final override def equals(other:Any)={ 42 val that = other.asInstanceOf[Programmer] 43 if(that==null)false 44 else name == that.name&&salary==that.salary 45 } 46 /** 47 * 1.hashCode()方法存在的主要目的就是提升效率。 48 * 2.在集合中判斷兩個對象相等的條件,其實不管是往集合中存數據, 49 * 仍是從集合中取數據,包括若是控制惟一性等,都是用這個條件判斷的,條件以下: 50 * 首先判斷兩個對象的hashCode是否相等,若是不相等,就認爲這兩個對象不相等,就完成了。 51 * 若是相等,纔會判斷兩個對象的equals()是否相等,若是不相等,就認爲這兩個對象不相等, 52 * 若是相等,那就認爲這兩個對象相等。 53 54 * 因此說重寫equals時必須重寫hashcode,這是良好的習慣 55 */ 56 final override def hashCode=name.hashCode()*5+salary.hashCode()*9 57 58 } 59 60 //object OverrideField { 61 // def main(args: Array[String]): Unit = { 62 // val s = new Sporter 63 // println(s.counterArray.length) 64 // } 65 //} 66 //第二種寫法,不用寫main函數 67 object OverrideField extends App{ 68 val s = new Sporter 69 println(s.counterArray.length) 70 }
注:對於無序表尋找是否有相同的對象時,使用hashcode能夠大大提升速度。equal的比較一般比較耗資源,能夠先比較hashcode後,確認hashcode相同時再用equal比較。ide
hashcode相同,equal不必定相同;equal相同的hashcode必定相同。函數
類的提取器:(中)this
1 package com.dtspark.scala.basics 2 /** 3 * 類的提取器 4 * 註解要搞懂下面兩個 5 * @transient 註解將字段標記爲瞬態的 6 * @volatile 註解標記爲易失的 7 * 8 * 本身編寫的註解要繼承annotation.Annotation 9 */ 10 case class Person1(name:String ,age:Int) 11 12 class DTCoder(val name:String ,val salary:Int) 13 object DTCoder{ 14 //複寫了其apply和unapply方法 15 def apply(name:String,salary:Int)={ 16 println("DTCoder apply method invoked!!!") 17 new DTCoder(name,salary) 18 } 19 // 方法1 (可以使一個字符串轉換成一個對象) 20 // def unapply(information:String)={ 21 // //根據空格區分參數 22 // println("DTCoder unapply method invoked!!!") 23 // Some((information.substring(0 , information.indexOf(" ")),information.substring(information.indexOf(" ")+1))) 24 // } 25 //方法二 26 def unapply(information:DTCoder)={ 27 //根據空格區分參數 28 println("DTCoder unapply method invoked!!!") 29 Some((information.name,information.salary)) 30 } 31 } 32 33 object HelloExtractor { 34 def main(args: Array[String]): Unit = { 35 val person=Person1("Spark",12)//調用apply的工廠構造方法,構造出類的實例 36 //= val person =Person1.apply("Spark",12) 37 val Person1(name,age)=person//調用Person1的unapply的方法把person實例中的name和age提取出來 38 println(person.name+" : "+person.age)//實現了name和age的賦值。 39 40 person match{ //val Person1(name,age)=person=match這個過程 41 case Person1(name,age)=>println(name+" : "+age) 42 } 43 //針對unapply方法一 44 //val DTCoder(dtname,salary) = "Spark 16000000" 45 46 //針對unapply方法二 47 val coder = DTCoder("Spark",2999999) 48 val DTCoder(dtname,salary)=coder 49 } 50 }
類的伴生對象:(高)spa
添加類的內容:scala
1 class Marker ( color:String) 2 class Marker (val color:String) 3 class Marker (var color:String)
這兩種申明是有差的,第二種和第三種申明均可以經過Marker的對象+"."直接調用(至關於這個屬性是靜態的),而第一種申明不行code
1 class Marker private (val color:String) { 2 3 println("建立" + this) 4 5 override def toString(): String = "顏色標記:"+ color 6 7 }
private寫在類名和參數中間表示對主構造函數的私有化,這時是不能new出對象的(除非有伴生對象object或者有重構this構造函數)orm
1 def main(args: Array[String]) { 2 new Marker("black")//報錯 3 }
1 object zcb01 { 2 def main(args: Array[String]) { 3 Marker("white") //直接對象名進行初始化 4 } 5 6 } 7 class Marker (val color:String) { 8 9 println("建立" + this) 10 11 override def toString(): String = "顏色標記:"+ color 12 13 } 14 15 16 object Marker{ 17 18 private val markers: Map[String, Marker] = Map( 19 "red" -> new Marker("red"), 20 "blue" -> new Marker("blue"), 21 "green" -> new Marker("green") 22 ) 23 private val m = Set(new Marker("black")) 24 def apply(color:String) = { 25 if(markers.contains(color)) markers(color) else null 26 println("我輸入的顏色:"+color) 27 } 28 29 }
結果:(先將object中的元素初始化,而後再調用apply方法初始化當前對象)對象
建立顏色標記:red
建立顏色標記:blue
建立顏色標記:green
建立顏色標記:black
我輸入的顏色:white
1 object zcb01 { 2 def main(args: Array[String]) { 3 new Marker("white",4) 4 } 5 6 } 7 class Marker private (val color:String) {//主構造的形式與類名後面的形式相同 8 9 println("建立" + this) 10 var a=1; 11 12 def this(color:String,a:Int){ 13 this(color)//必須先調用主構造器 14 this.a=a; 15 } 16 17 override def toString(): String = "顏色標記:"+ color 18 19 }