日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Scala入门到精通——第八节 包和引入

發布時間:2024/1/23 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Scala入门到精通——第八节 包和引入 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本節主要內容

  • 包的作用與定義
  • 包的作用域與引入(import)的使用方法
  • 訪問控制
  • 包對象
  • import高級特性
  • 內部類
  • 包的作用與定義

    同Java中的包、C++中的命名空間一樣,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() }
    • 1

    上述包也可通過下面的包定義方式進行:

    //下面的代碼定義了一個cn.scala.xtwy包 //在程序的任何地方都可以通過cn.scala.xtwy.Teacher來使用Teacher這個類 package cn{package scala{package xtwy{class Teacher {}}} }
    • 1

    將上面的代碼命名為Teacher.scala,代碼組織如下:

    可以看到我們將代碼放在默認包下面,但編碼后的字節碼文件被自動組織到cn.scala.xtwy文件夾當中,如下圖

    可以看出,我們可以在任何地方進行包中類的定義,scala幫助我們進行自動文件組織

    我們將Teacher.scala內容修改如下:

    package cn{package scala{package xtwy{class Teacher {}}} } //添加了cn.scala.spark包,包中定義了一個SparkDemo類 package cn{package scala{package spark{class SparkDemo{}}} }
    • 1

    下圖給出的是Teacher.scala編譯后產生的包文件:

    通過前面的介紹,我們知道了如何定義包,包是怎么組織代碼的。在實際開發過程當中,盡量使用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.xtwypackage 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() }}

    訪問控制

    在java語言中,主要通過public、private、protected及默認控制來實現包中類成員的訪問控制,當定義一個類時,如果類成員不加任何訪問控制符時,表示該類成員在定義該類的包中可見。在scala中沒有public關鍵字,僅有private 和 protected訪問控制符,當一個類成員不加private和protected時,它的訪問權限就是public。下面逐個進行講解:

    1 private 成員
    private成員同java是一樣的,所有帶該關鍵字修飾的成員僅能在定義它的類或對象中使用,在外部是不可見的

    class Student(var name:String,var age:Int){private var sex:Int=0//內部類class Course(val cName:String,val gpa:Float){//可以直接訪問其外部類的私有成員def getStudentSex(student:Student)= student.sex} }//班級類 class Class{//下面這條語句統計通不過,因為sex是私有的// def getStudentSex(student:Student)=student.sex } object Student {private var studentNo:Int=0;def uniqueStudentNo()={studentNo+=1studentNo}def apply(name:String,age:Int)=new Student(name,age)def main(args: Array[String]): Unit = {println(Student.uniqueStudentNo())val s=new Student("john",29)//直接訪問伴生類Student中的私有成員println(s.sex)val s1=Student("john",29)println(s1.name)println(s1.age)//使用內部類val c1=new s1.Course("Scala",3.0f)} }

    2 protected 成員
    在java語言中,protected成員不但可以被該類及其子類訪問,也可以被同一個包中的其它類使用,但在scala中,protected成員只能被該類及其子類訪問

    class SuperClass {protected def f()=println(".....") }class SubClass extends SuperClass{f() }class OtherClass{//下面這個語句會報錯//f() }

    3 無修飾符成員
    無修飾符的成員同java 的public,可以在任何位置進行訪問

    4 范圍保護
    在scala中提供了更為靈活的訪問控制方法,private、protected除了可以直接修飾成員外,還可以以private[X]、protected[X]的方式進行更為靈活的訪問控制,這種訪問控制的意思是可以將private、protected限定到X,X可以是包、類,還可以是單例對象

    package cn{class UtilsTest{//編譯通不過,因為Utils利用private[scala]修飾,只能在scala及其子包中使用//Utils.toString()}package scala{//private[scala]限定Utils只能在scala及子包中使用private[scala] object Utils{def toString(x:String){println(x)}import cn.scala.xtwy._def getTeacher():Teacher=new Teacher("john")}package xtwy{class Teacher(var name:String) {def printName()={Utils.toString(name)}}}} } object appDemo{import cn.scala._import cn.scala.xtwy._def main(args: Array[String]): Unit = {//編譯通不過,同UtilsTest//Utils.toString(new Teacher("john").name)new Teacher("john").printName() }}

    private[this],限定只有該類的對象才能訪問,稱這種成員為對象私有成員

    package cn.scala.xtwy;class Teacher(var name: String) {private[this] def printName(tName:String="") :Unit= { println(tName) }//調用private[this] printName方法def print(n:String)=this.printName(n) }object Teacher{//private[this]限定的成員,即使伴生對象Teacher也不能使用//def printName=new Teacher("john").printName() }object appDemo {def main(args: Array[String]): Unit = {//編譯不能通過//new Teacher("john").printName()}}

    private,定義的類及伴生對象可以訪問

    package cn.scala.xtwy;class Teacher(var name: String) {private def printName(tName:String="") :Unit= { println(tName) }//可以訪問def print(n:String)=this.printName(n) }object Teacher{//伴生對象可以訪問def printName=new Teacher("john").printName() }object appDemo {def main(args: Array[String]): Unit = {//不能訪問//new Teacher("john").printName()}}

    下面給出的是訪問規則表

    修飾符訪問范圍
    無任何修飾符任何地方都可以使用
    private[scala]在定義的類中可以訪問,在scala包及子包中可以訪問
    private[this]只能在定義的類中訪問,即使伴生對象也不能訪問團
    private在定義的的類及伴生對象中可以訪問,其它地方不能訪問
    protected[scala]在定義的類及子類中可以訪問,在scala包及子包中可以訪問,
    protected[this]只能在定義的類及子類中訪問,即使伴生對象也不能訪問
    protected在定義的類及子類中訪問,伴生對象可以訪問,其它地方不能訪問

    包對象

    包對象主要用于將常量、工具函數,使用時直接通過包名引用

    //下面的代碼給出了包對象的定義 package cn.scala.xtwy//利用package關鍵字定義單例對象 package object Math {val PI=3.141529val THETA=2.0val SIGMA=1.9 }class Coputation{def computeArea(r:Double)=Math.PI*r*r }

    上述代碼編譯后會生成下列文件:

    對應字節碼文件如下:

    D:\ScalaWorkspace\ScalaChapter08\bin\cn\scala\xtwy\Math>javap -private package.c lass Compiled from "Math.scala" public final class cn.scala.xtwy.Math.package {public static double SIGMA();public static double THETA();public static double PI(); }D:\ScalaWorkspace\ScalaChapter08\bin\cn\scala\xtwy\Math>javap -private package$. class Compiled from "Math.scala" public final class cn.scala.xtwy.Math.package$ {public static final cn.scala.xtwy.Math.package$ MODULE$;private final double PI;private final double THETA;private final double SIGMA;public static {};public double PI();public double THETA();public double SIGMA();private cn.scala.xtwy.Math.package$(); }

    不能看出,它為我們的包對象Math創建了一個文件夾,然后創建了兩個類,通過單例的方式實現方法調用。

    import高級特性

    1 隱式引入
    在集合那一講,我們提到,如果不引入任何包,scala會默認引入java.lang._
    scala._
    Predef._
    包中或對象中所有的類和方法,稱這種引入會隱式引入

    2 重命名

    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 JavaHashMap[String, String]()javaHashMap.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)=eprintln(k+":"+v)})}}

    3 類隱藏

    //通過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)=eprintln(k+":"+v)})}
    • 1

    內部類

    前面我們提到過內部類,我們看到內部類可以像類的其它成員一樣訪問外部類的私有成員,本小節將對內部類進行更加詳細的介紹。

    要點1:外部類不能訪問內部類的成員域,但內部類可以直接訪問外部類成員域,哪怕這個成員域是private私有的

    class OuterClass {//即使定義為 private[this] var x:Int=0,也是可行的private var x:Int=0//def getInnerY=y,外部類不能直接訪問內部類的成員域class InnerClass{private var y:Int=0//內部的類可以直接訪問外部類的成員變量和成員方法,注意外部類的成員變量是privatedef getOuterX= x} }object AppDemo{def main(args: Array[String]): Unit = {val o=new OuterClass//創建內部類對象,通過o.InnerClass方式,InnerClass就像是OuterClass的成員變量一樣val i=new o.InnerClassprintln(i.getOuterX)} }

    從上述代碼可以看出,內部類除了是一個類之外,與外部類的成員沒有任何區別,它可以與外部類的成員域一樣被使用。

    總結

    以上是生活随笔為你收集整理的Scala入门到精通——第八节 包和引入的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。