<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] # 類定義 在scala類中,與類名相同的對象叫做伴生對象,類和伴生對象之間可以相互訪問私有的方法和屬性 ~~~ //scala中,類不必聲明為public //scala源文件中可以包含多個類,所有這些類都具有公有可見性 class Person { //用val修飾的變量是只讀屬性,有getter但沒有setter(相當于java中用final修飾的變量) val id = "9527" //用var修飾的變量既有getter又有setter var age: Int = 18 //類私有字段,只能在類的內部使用 private var name: String = "唐伯虎" //對象私有字段,訪問權限更加嚴格,Person類的方法只能訪問到當前對象的字段 private[this] val pet = "小強" def sayHi(): Unit = { println(name) println(pet) println("------------") } } //(單例對象,靜態對象) //伴生對象: 與類名相同并且在同一個文件中 object Person { def main(args: Array[String]): Unit = { val p = new Person() println(p.id) println(p.age) p.age=20 println(p.age) println(p.name) p.name="abc" println(p.name) //pet訪問不到 } } ~~~ # 構造器 主構造器中的參數使用后會被升級為字段 ~~~ //每個類都有主構造器,主構造器的參數直接放置類名后面,與類交織在一起 class Student(val name: String, val age: Int, faceValue: Double = 99.99, private var height: Int = 18) { //主構造器會執行類定義中的所有語句 println("執行主構造器") private[this] var gender: String = null def show(): Unit = { println(faceValue) } //輔助構造器 def this (參數),可以重載 def this(name: String, age: Int, gender: String) { //輔助構造器第一行,一定要調用主構造器 this(name, age) this.gender = gender } } object Student { def main(args: Array[String]): Unit = { val p = new Student("zx", 30, 100) println(p.age) println(p.name) } } ~~~ **私有主類構造器** ~~~ class Student private(val name: String, val age: Int, faceValue: Double = 99.99, private var height: Int = 18) { ~~~ 這樣用戶只能通過輔助構造器來構造對象了 **限制包使用** ~~~ private[cn] class Student private(val name: String, val age: Int, faceValue: Double = 99.99, private var height: Int = 18) { ~~~ # 單例對象 在scala中沒有靜態方法和靜態字段,但是可以使用object這個語法結構來達到同樣的目的 ~~~ class SingletonDemo { } object SingletonDemo { def main(args: Array[String]): Unit = { val s1 = SingletonDemo val s2 = new SingletonDemo val s3 = SingletonDemo println(s1) println(s2) println(s3) } } ~~~ 輸出 ~~~ SingletonDemo$@6debcae2 SingletonDemo@5ba23b66 SingletonDemo$@6debcae2 ~~~ 在伴生對象內,不用new就是單例 # apply方法 通常我們會在類的伴生對象中定義apply方法,當遇到類名(參數1,...參數n)時apply方法會被調用 ~~~ object ApplyDemo { def apply(): Unit = { println("apply invoked") } def main(args: Array[String]): Unit = { val a = ApplyDemo() println(a) } } ~~~ # 繼承 在scala中重寫一個非抽象的方法必須使用override修飾符 **類型檢查和轉換** | scala | java | | --- | --- | | obj.isInstanceOf[C] | obj instanceof C | | obj.asInstanceof[C] | (C)obj | | classOf[C] | C.class | ~~~ //接口,但是可以有實現 trait Flyable{ def fly(): Unit = { println("I can fly") } def fight(): String } abstract class Animal { def run(): Int val name: String } //如果接口是第一個實現的,也用extends,后面的用with class Human extends Animal with Flyable { val name = "abc" //在scala中重寫一個非抽象方法必須用override修飾 override def fight(): String = { "fight" } //在子類中重寫超類的抽象方法時,不需要使用override關鍵字,寫了也可以 def run(): Int = { 1 } } ~~~ # 靜態方法和非靜態方法 調用方法,靜態方法(scala中沒有靜態方法這個概念,需要通過伴生類對象來實現) ~~~ scala> BigInt.probablePrime(16, scala.util.Random) ~~~ 調用方法,非靜態方法,使用對象調用 ~~~ scala> "HelloWorld".distinct ~~~ # 對象私有化字段 變量: workDetails在封閉包professional中的任何類中可訪問 封閉包: friends的任何類都可以被society包中任何類訪問 變量: secrets只能在實例方法的隱式對象(this)中訪問 ~~~ package unit7{ package society { package professional { class Executive { private[professional] var workDetails = null private[society] var friends = null private[this] var secrets = null def help(another: Executive): Unit = { println(another.workDetails) //another是不能用的,因為他是其他對象 // println(another.secrets) } } } } } ~~~ ![](https://box.kancloud.cn/7ae1a396df154493dde68c493613e9aa_946x198.png) # 嵌套類 在class中,再定義一個class,以此類推 java中的內部類從屬于外部類.scala中內部類從屬于實例 ~~~ class Network { class Member(val name: String) { val contacts = new ArrayBuffer[Member] } private val members = new ArrayBuffer[Member] def join(name: String) = { val m = new Member(name) members += m m } } ~~~ 這里的member沒有指定是屬于類的還是對象的 實際上是屬于對象的 這個代碼會報錯 ~~~ object ObjectDemo extends App { val network1 = new Network val nick = network1.join("Nick") //network1.Member val alice = network1.join("Alice") //network1.Member nick.contacts += alice alice.contacts += nick val network2 = new Network val jone = network2.join("Jone") //network2.Member nick.contacts += jone } ~~~ 指定屬于哪個對象的就不會報錯了 ~~~ class Network { private val members = new ArrayBuffer[Network.Member] def join(name: String) = { val m = new Network.Member(name) members += m m } } object Network { class Member(name: String) { val contacts = new ArrayBuffer[Member]() } } ~~~ 注意: 類和他的伴生對象可以相互訪問私有特性,他們必須存在同一個源文件中.必須同名 # 枚舉 scala中沒有枚舉類型,定義一個擴展Enumeration類的對象,并以value調用初始化枚舉中的所有可能值 ~~~ object TrafficLightColor extends Enumeration { val Red = Value(0, "stop") val Yello = Value(1, "slow") val Green = Value(2, "Go") } object ObjectDemo extends App { println(TrafficLightColor.Red) println(TrafficLightColor.Yello) println(TrafficLightColor.Green.id) } ~~~ # 包和引用 在java和scala中管理項目可以使用包結構,c和c#使用命名空間 對于package,有如下幾種形式 ~~~ package com package nick.impatient package people class Person { val name = "Nick" def play(message: String): Unit = { } } ~~~ 等同于 ~~~ package com.nick.impatient { //com和com.nick在這不可見 package people { class Person { val name = "Nick" def play(message: String): Unit = { } } } } ~~~ 提示: 在文件頂部不帶花括號的包聲明在整個文件范圍內有效 訪問父package中的內容.(即:作用域) 包對象可以持有函數和變量 引入語句可以引入包,類和對象 源文件的目錄和包之間并沒有強制的關聯關系 可以在同一個.scala文件中,聲明多個并列的package 包名可以相對也可以絕對,比如,訪問ArrayBuffer的絕對路徑是: `_root_.scala.collection.mutable.ArrayBuffer` ## 包對象 包可以包含類,對象和特質trait,**但是不能包含函數或變量的定義**.很不幸,這是java虛擬機的局限. 把工具函數或常量添加到包而不是某個utils對象,這是更加合理的做法.包對象出現正是為了解決這個局限.**每個包都可以有一個包對象**.**你需要在父包中定義他**,而且名稱與子包一樣 ~~~ package object people { val defaultName = "Nick"; } package people { class people { //從包對象拿到的 val name = defaultName } } ~~~ ## 包可見性 在java中,沒有聲明為public,private或protected的類成員在包含類的包中可見. 在scala中,你可以通過修飾符達到同樣的效果 ~~~ package com.nick.impatient.people class Person { //只在當前包可見 private[people] def description = "desc" //可以將可見度延展到上層包 private[impatient] def name = "name" } ~~~ ## **重命名** 如果你想要引入包中的幾個成員,可以像這樣使用選取器(selector),而且選取的通俗,可以重命名 ~~~ import java.util.{HashMap=>JavaHashMap, List} ~~~ 這樣一來,javaHashMap就是java.util.HashMap,而HashMap對應scala.collection.mutable.HashMap # 受保護的字段和方法 protected在scala中比java要跟嚴格一點,只有繼承關系才可以訪問,同一個包下,也是不可以的 # 超類構造 類有一個主構造器和任意數量的輔助構造器,而每個輔助構造器都必須對先前定義的輔助構造器或主構造器的調用開始. 子類的輔助構造器最終都會調用主構造器,只有主構造器可以調用超類的構造器,輔助構造器永遠不可能直接調用超類的構造器. 在scala的構造器中,你不能調用super(params) * 當前類的(輔助構造器),最終都會調用當前類的(主構造器) * 子類的主構造器,最終都會調用父類的構造器(可以是輔助構造器,可以是主構造器) ~~~ class Animal(age: Int, hairColor: String) { } //可以給默認值 class Dog(age: Int, hairColor: String) extends Animal(age, hairColor = "11") { } ~~~ # 抽象類 可以通過abbstract關鍵字標記不能被實例化的類.方法不用標記abstract,只要省掉方法體即可. 抽象類可以擁有抽象字段 抽象字段就是沒有初始值的字段 ~~~ abstract class Person(val pname: String) { val id: Int var name: String def idString: Int def play: Unit } class Employee(pname: String) extends Person(pname) { val id = 5; var name = ">>>" def idString = pname.hashCode override def play: Unit = { println(name) } } ~~~ # 構造順序和提前定義 ~~~ class Father { val range = 10 val arr = new ArrayBuffer(range) } class Child extends Father { override val range = 20 } ~~~ 1. new Father --- 初始化range變量等于10 --- 發現該變量被子類覆寫了 --- 提取range值,去子類中提取,通過提取器,提取子類中的range值 = 0 --- new ArrayBuffer(range = 0) 2. new Child --- 覆寫range = 20 打印 --- arr.length = 0 --- range = 20 問題解決: 3種方案 1. 可以將val聲明為final,這樣子類不可改寫 2. 可以將超類中將val聲明為lazy,這樣安全但是并不高效 3. 還可以使用提前定義語法,可以在超類的構造器執行之前初始化子類的val字段: ~~~ class Ant2 extends { override val range = 3 } with Creature ~~~ 里面大括號表示是Creature的子類,并且在初始化的時候先初始化這個匿名類 # scala繼承層級 在scala中,所有其他類都是AnyRef的子類,類似java的Object AnyVal和AnyRef都擴展自Any類.Any類是根節點 Any中定義了isInstanceOf,asInstanceOf方法,以及哈希方法等 Null類型的唯一實例就是null對象.可以將null賦值給任何引用,但不能賦值給值類型的變量 # 當做接口使用的特質 特質中沒有實現的方法就是抽象方法.類通過extends繼承特質,通過with可以繼承多個特質 ~~~ trait Logger { def log(msg: String) } class ConsoleLogger extends Logger with Cloneable with Serializable { override def log(msg: String): Unit = { println(msg) } } ~~~ 特質中的方法并不一定是抽象的 ## 混入 ~~~ /** * 疊加特質的執行順序 * 1. 動態混入: 右向左執行 * 2. 情景: 混入的多個特質,是繼承了同一個特質 * 3. super關鍵字為向左調用 */ trait Logger3 { def log(msg: String) } trait ConsoleLogger3 extends Logger3 { def log(msg: String) { println(msg) } } trait TimestampLogger3 extends ConsoleLogger3 { override def log(msg: String) { super.log(new java.util.Date() + " " + msg) } } trait ShortLogger3 extends ConsoleLogger3 { override def log(msg: String): Unit = { super.log(if (msg.length <= 15) msg else s"${msg.substring(0, 12)}...") } } class Account3 { protected var balance = 0.0 } abstract class SavingsAccount3 extends Account3 with Logger3 { def withdraw(amount: Double) { //沒有實體下面有混入的 if (amount > balance) log("余額不足") else balance -= amount } } object Main3 extends App { //TimestampLogger3 // val acct1 = new SavingsAccount3 with TimestampLogger3 with ShortLogger3 // acct1.withdraw(100) //ShortLogger3 val acct1 = new SavingsAccount3 with ShortLogger3 with TimestampLogger3 acct1.withdraw(100) } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看