1. 程式人生 > >三分鐘讓你瞭解Scala中的包比Java更加靈活!

三分鐘讓你瞭解Scala中的包比Java更加靈活!

  包的作用和定義   同java中的包,Scala中的包主要用於大型工程程式碼的組織同時也解決命名衝突的問 題。Scala中的包與java有著諸多的相似之處,但Scala語言中的包更加靈活。   包定義方式一:   //將程式碼組織到cn.scala.xtwy包中 package cn.scala.xtwyabstract class Animal { //抽象欄位(域) var height:Int //抽象方法 def eat:Unit }   class Person(var height:Int) extends Animal{ override def eat()={ println("eat by mouth") }   }   object Person extends App{ new Person(10).eat() }   + 包定義方式二: //下面的程式碼定義了一個cn.scala.xtwy包 //在程式的任何地方都可以通過cn.scala.xtwy.Teacher來使用Teacher這個類package cn{ package scala{ package xtwy{ class Teacher {}   }   } }可以看出,我們可以在任何地方進行包中類的定義,scala幫助我們進行自動檔案組織 我們將Teacher.scala內容修改如下:package cn{ package scala{ package xtwy{ class Teacher {}   }   } } //添加了cn.scala.spark包,包中定義了一個SparkDemo類 package cn{ package scala{ package spark{ class SparkDemo{}   }   } }

通過前面的介紹,我們知道了如何定義包,包是怎麼組織程式碼的。在實際開發過程當中,儘量使用java包的定義方式並將程式碼集中進行管理,這樣別人讀程式碼的時候更方便,程式碼更簡潔。   包的作用域與引入(import)的使用方法   下面的程式碼給出了包的作用域和引入的使用方法package cn{ package scala{ //在包cn.scala下建立了一個Utils單例 object Utils{ def toString(x:String){ println(x) } //外層包無法直接訪問內層包,下面這一行程式碼編譯通不過 //def getTeacher():Teacher=new Teacher("john") //如果一定要使用的話,可以引入包 import cn.scala.xtwy._ def getTeacher():Teacher=new Teacher("john") } //定義了cn.scala.xtwy package xtwy{ class Teacher(var name:String) { //演示包的訪問規則 //內層包可以訪問外層包中定義的類或物件,無需引入 def printName()={Utils.toString(name)} }   }   } } object appDemo{ //scala允許在任何地方進行包的引入,的意思是引入該包下的所有類和物件 import cn.scala. import cn.scala.xtwy._ def main(args: Array[String]): Unit = { Utils.toString(new Teacher("john").name) new Teacher("john").printName() }   }
  Scala訪問修飾符   Scala 訪問修飾符分別有:private,protected,public。   如果沒有指定訪問修飾符符,預設情況下,Scala 物件的訪問級別都是 public。   Scala 中的 private 限定符,比 Java 更嚴格,在巢狀類情況下,外層類甚至不能訪問被巢狀類的私有成員。   私有(Private)成員   用private關鍵字修飾,帶有此標記的成員僅在包含了成員定義的類或物件內部可見,同樣的規則還適用內部類。   class Outer{ class Inner{ private def f(){println(“f”)} class InnerMost{ f() // 正確 } } (new Inner).f() //錯誤 }(new Inner).f( )訪問不合法是因為f在Inner中被宣告為private,而訪問不在類Inner之內。   保護(Protected)成員   在scala中,只允許保護成員在定義了該成員的的類的子類中被訪問。   package p{ class Super{ protected def f() {println(“f”)} } class Sub extends Super{ f() } class Other{ (new Super).f() //錯誤 } }   上例中,Sub 類對 f 的訪問沒有問題,因為 f 在 Super 中被宣告為 protected,而 Sub 是 Super 的子類。相反,Other 對 f 的訪問不被允許,因為 other 沒有繼承自 Super。   公共(Public)成員   Scala中,如果沒有指定任何的修飾符,則預設為public。這樣的成員在任何地方都可以被訪問。   class Outer { class Inner { def f() { println(“f”) } class InnerMost { f() // 正確 } } (new Inner).f() // 正確因為 f() 是 public }   作用域保護   Scala中,訪問修飾符可以通過使用限定詞強調。格式為:   private[x]   或   protected[x]   這裡的x指代某個所屬的包、類或單例物件。如果寫成private[x],讀作"這個成員除了對[…]中的類或[…]中的包中的類及它們的伴生對像可見外,對其它所有類都是private。   這種技巧在橫跨了若干包的大型專案中非常有用,它允許你定義一些在你專案的若干子包中可見但對於專案外部的客戶卻始終不可見的東西。   package bobsrocckets{ package navigation{ private[bobsrockets] class Navigator{ protected[navigation] def useStarChart(){} class LegOfJourney{ private[Navigator] val distance = 100 } private[this] var speed = 200 } } package launch{ import navigation._ object Vehicle{ private[launch] val guide = new Navigator } } }上述例子中,類Navigator被標記為private[bobsrockets]就是說這個類對包含在bobsrockets包裡的所有的類和物件可見。   比如說,從Vehicle物件裡對Navigator的訪問是被允許的,因為物件Vehicle包含在包launch中,而launch包在bobsrockets中,相反,所有在包bobsrockets之外的程式碼都不能訪問類Navigator。   下面給出的是訪問規則表   | 修飾符 | 訪問範圍 | | ------------- |:-------------? | 無任何修飾符| 任何地方都可以使用|| private[scala] | 在定義的類中可以訪問,在scala包及子包中可以訪問|| private[this] | 只能在定義的類中訪問,即使伴生物件也不能訪問團| |private |在定義的的類及伴生物件中可以訪問,其它地方不能訪問| |protected[scala] |在定義的類及子類中可以訪問,在scala包及子包中可以訪問| |protected[this] |只能在定義的類及子類中訪問,即使伴生物件也不能訪問| |protected|在定義的類及子類中訪問,伴生物件可以訪問,其它地方不能訪問|包物件   包物件主要用於將常量、工具函式,使用時直接通過包名引用 //下面的程式碼給出了包物件的定義 package cn.scala.xtwy//利用package關鍵字定義單例物件 package object Math { val PI=3.141529 val THETA=2.0 val SIGMA=1.9 }   class Coputation{ def computeArea(r:Double)=Math.PIrr }
import高階特性   隱式引入 在集合那一講,我們提到,如果不引入任何包,scala會預設引入java.lang._ scala._ Predef._ 包中或物件中所有的類和方法,稱這種引入會隱式引入重新命名 scala中允許對引入的類或方法進行重新命名,如果我們需要在程式中同時使用java.util.HashMap及scala.collection.mutable.HashMap時,可以利用重新命名的方法消除命名衝突的問題,雖然也可以採用包名字首的方式使用,但程式碼不夠簡潔//將java.util.HashMap重新命名為JavaHashMap import java.util.{ HashMap => JavaHashMap } import scala.collection.mutable.HashMap object RenameUsage { def main(args: Array[String]): Unit = { val javaHashMap = new JavaHashMapString, StringjavaHashMap.put("Spark", "excellent") javaHashMap.put("MapReduce", "good") for(key <- javaHashMap.keySet().toArray){ println(key+":"+javaHashMap.get(key)) }   val scalaHashMap=new HashMap[String,String]   scalaHashMap.put("Spark", "excellent")   scalaHashMap.put("MapReduce", "good")   scalaHashMap.foreach(e=>{   val (k,v)=e   println(k+":"+v)   })   }   } + 隱藏類 //通過HashMap=> _,這樣類便被隱藏起來了 import java.util.{HashMap=> ,} import scala.collection.mutable.HashMapobject RenameUsage { def main(args: Array[String]): Unit = {//這樣的話,HashMap便無歧義地指向scala.collection.mutable.HashMapval scalaHashMap=new HashMap[String,String]   scalaHashMap.put("Spark", "excellent")   scalaHashMap.put("MapReduce", "good")   scalaHashMap.foreach(e=>{   val (k,v)=e   println(k+":"+v)   })   }   文章來自:https://www.itjmd.com/news/show-2216.html