Scala 的學習

JD_L發表於2023-05-10

Scala

只是學習無基本理論

安裝Scala

裝前必須有jdk

windows安裝

解壓縮 D:dev/scala

配置環境變數

SCALA_HONE

path

cmd檢查

Scala -version

直接輸入Scala 控制檯執行

idea安裝與執行Scala

idea-->外掛-->scala-->安裝-->重啟

新建maven專案

catalog-->maven

archetype-->

image

專案結構-->全域性庫-->新增Scala

image

image

新增應用支援-->scala
add開頭
image

image

新建Scala類 選擇 object

image

scala 完全物件導向

scala風格與java風格

public class JavaDemo01 {
    public static void main(String[] args) {
        System.out.println("我愛你中國");
    }
}
javac JavaDemo01
object ScalaDemo01{
    def main(args: Array[String]): Unit = {
    print("我愛你中國")
  }
}
scalac ScalaDemo01

終端執行Scala

編碼 utf-8

scalac 檔名字--> 生成 檔名字$.class 與 檔名字.class-->呼叫 檔名字.class

Scala專案啟動方式

main函式與extends app特質的區別:

App是scala語言內建的一個特質,使用它,則把對應object內部的整體作為scala main的一部分,有延遲啟動的特性。

同時,命令列引數args也作為App特質的一部分,可以被開發者直接使用。而main函式則是scala的預設啟動方式。

使用main函式

object ScalaDemo02{
    def main(args: Array[String]): Unit = {
    print("我愛你中國")
  }
}

使用App特質

object ScalaDemo03 extends App{
    print("我愛你中國")
}
object ScalaDemo04 extends App{
    print(args(0))
}

終端執行:

scalac ScalaDemo04.scala
scala ScalaDemo04 lhz

Scala程式碼與Java程式碼混用

object ScalaDemo05{
    def main(args: Array[String]): Unit = {
    System.out.println("我愛你中國")
  }
}

在 Scala 程式碼中 可以直接使用 Java 程式碼

注意:main 方法使用Scala 風格

變數與常量

object ScalaDemo06{
    def main(args: Array[String]): Unit = {
    // var 變數 修飾符
        var a:Int = 10
    // val 常量 修飾符
    	val b:Int = 10
        
        a = 20
        println(a)
        /**
         *報錯
         *reassignment to val
        */
        // b = 20
  }
}

字串基本使用

object ScalaDemo07{
    def main(args: Array[String]): Unit = {
        var str01:String = "我愛你"
        var str02:String = "中國"
        // java 風格
        println (str01 + str02)
        // 插值方式 與 python 風格比較相像
        var slogan:String = "桃李不言下自成蹊"
        println(s"slogan >>> $slogan")
        
        println("""
        	|我愛你中國
        	|親愛的母親
        """.strpMargin)
  }
}

選擇結構

object ScalaDemo08{
    def main(args: Array[String]): Unit = {
        var weekDay:Int = 1
        if (weekDay == 1){
            println("週一")
        }else if (weekDay == 2){
            println("週二")
        }else if (weekDay == 3){
            println("週三")
        }else if (weekDay == 4){
            println("週四")
        }else if (weekDay == 5){
            println("週五")
        }else if (weekDay == 6){
            println("週六")
        }else{
            println("週日")
  	}
  }
}

迴圈結構

object ScalaDemo09{
    def main(args: Array[String]): Unit = {
        var count:Int = 0
        while(count<5){
            println(count)
            count += 1
        }
  }
}
object ScalaDemo10{
    def main(args: Array[String]): Unit = {
        //Range 1 to 5
        println(1 to 5)
        println(1.to(5))
        println(1 until 5)
        println(1.until(5))
        
        // <- 賦值
        for (i <- 0 until 5){
            println(i)
        }
        println("--------------------^_ ~ _^----------------------")
        // 求偶數值
        for (i <- 0 until 10){
            if (i % 2 == 0){
                println(i)
            }
        }
        println("--------------^_ ~ _^----------------")
        for (i <- 0 until 10 if i % 2 == 0){
            println(i)
        }
        println("--------------^_ ~ _^----------------")
        for (i <- 0 until 10 by(2)){
            println(i)
        }
        println("--------------------^_ ~ _^----------------------")
        // 增強for迴圈
        var courses = Array("Hadoop","Hive","Sqoop","Flume","Hbase","Phoenix","Presto")
        for (course <- courses){
            println(course)
        }
  }
}

函式

無引數 無返回值

object ScalaDemo01{
    def main(args: Array[String]): Unit = {
    	sayHi()
  }
    // def 函式定義關鍵字 
    // sayHI 函式名稱
    // () 函式引數
    // :後面的資料型別為返回值資料型別
    // : Unit 無返回值的資料型別佔位符
    // {} 方法體
    private def sayHi(): Unit = {
      println("無引數 無返回值 函式 sayHi")  
    }
}

有引數 無返回值

object ScalaDemo02{
    def main(args: Array[String]): Unit = {
   	 sayHi(msg = "hello word")
  }
    private def sayHi(msg:String): Unit = {
        println("有引數 無返回值 函式 sayHi")
        println(s"引數是 >>> ${msg}")
    }
}

預設引數 無返回值

object ScalaDemo03{
    def main(args: Array[String]): Unit = {
    	sayHi()
        sayHi(msg = "hello")
  }
    private def sayHi(msg:String = "hi"): Unit = {
        println("預設引數 無返回值 函式 sayHi")
        println(s"引數是 >>> ${msg}")
    }
}
# 輸出結果:
預設引數 無返回值 函式 sayHi
引數是 >>> hi
預設引數 無返回值 函式 sayHi
引數是 >>> hello

有引數 有返回值

object ScalaDemo04{
    def main(args: Array[String]): Unit = {
    	println(sum(10,20))
  }
    def sum(a:Int , b:Int): Int ={
        // 函式的最後一行為返回值
        a+b
    }
}

可變引數 無返回值

public class JavaDemo04{
     public static void main(String[] args) {

    }
    private static String
}
object ScalaDemo05{
    def main(args: Array[String]): Unit = {
    	println(format())
        println(format(numbers = 1))
        println(format(numbers = 1,2))
  }
    def format(numbers: Int*): String = {
        // var result:String = null
        var result:Int = 0
    	if(numbers.size > 0){
            for(number <- numbers){
                result += number
            }
        }
        result
    }
}

物件導向

類與物件

object ScalaDemo01{
    def main(args: Array[String]): Unit = {
   		val person = new Person01
        person.name = "lhz"
        println(person.name)
  }
    class Person01{
        // _ 代表著 佔位符 佔位
        var name:String = _
    }
}

封裝

scala中屬性、方法預設為public

private只在類的內部和伴生物件中可用

protected,同類、子類可以訪問,同包無法訪問

private[包名],增加包訪問許可權,包名下的其他類也可以使用

Scala提供進一步的封裝,“public”屬性底層實際上都是private,訪問時本質上是呼叫了xxx(get) 和 xxx_eq$(set) 方法,

但這裡的方法名並不是getXXX和setXXX,由於一些Java框架會利用反射呼叫getXXX和setXXX,

因此Scala也提供了上面提到過的@BeanProperty註解去生成某屬性的這兩個方法,

但注意@BeanProperty不能加在private修飾的屬性上,

可以理解為由於“public”本身就是private,將變數修飾為private然後再提供getter、setter方法比較冗餘,Scala不推薦這樣做。

// 假 封裝
object ScalaDemo02{
    def main(args: Array[String]): Unit = {
   		val person = new Person02
        person.setName("lhz")
        println(person.getName)
        person.name = "lz"
        println(person.name)
  }
    class Person02{
        // _ 代表著 佔位符 佔位
        @BeanProperty
        var name:String = _
    }
}
// private 不推薦
// 手寫 set get 方法
object ScalaDemo03 {
  def main(args: Array[String]): Unit = {
   val person = new Person03
   person.setName("lhz")
   println(person.getName)
  }
  class Person03{
    private var name: String = _

    def getName: String = {
      this.name
    }

    def setName(name: String): Unit ={
      this.name = name
    }
  }
}

java程式碼混用

public class Person04 {
    private String realName;

    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }
}
object ScalaDemo04 {
  def main(args: Array[String]): Unit = {
    val person = new Person04
    person.setRealName("李昊哲")
    println(person.getRealName)
  }
}

建構函式

object ScalaDemo05{
    def main(args: Array[String]): Unit = {
   		val person01 = new Person05("person01","220422198311222011")
    val person02 = new Person05("person02","220422198311222011",15311484567L)
    val person03 = new Person05("person02","220422198311222011","我愛你中國")
    val person04 = new Person05("person02","220422198311222011",15311484568L,"我愛你中國")
    println(person01)
    println(person02)
    println(person03)
    println(person04)
  }
}
    //主建構函式
class Person05(val realName:String, val idCard:String){
	println("Person05 主構造器 執行了")
    var mobile: Long= _
    var slogan: String= _
        
    // 輔助構函式 輔助構函式不能有型別註解
    def this(realName: String , idCard: String, mobile: Long)={
            // 輔助構函式 的 第一行程式碼必須呼叫 主建構函式 或者其他 輔助構函式
            this(realName,idCard)
            this.mobile = mobile
        }
        def this(realName: String , idCard: String, Slogan: String)={
            // 輔助構函式 的 第一行程式碼必須呼叫 主建構函式 或者其他 輔助構函式
            this(realName,idCard)
            this.slogan = slogan
        }
        def this(realName: String , idCard: String, mobile: Long, slogan: String)={
            // 輔助構函式 的 第一行程式碼必須呼叫 主建構函式 或者其他 輔助構函式
            this(realName,idCard,mobile)
            this.slogan = slogan
        }
    override def toString: String =
    this.getClass.getSimpleName +
      ", realName:" + realName +
      ", idCard:"+ idCard +
      ", mobile:" + mobile +
      ", slogan:"  + slogan

}

執行結果

Person05 主構造器 執行了
Person05 主構造器 執行了
Person05 主構造器 執行了
Person05 主構造器 執行了
Person05, realName:person01, idCard:220422198311222011, mobile:0, slogan:null
Person05, realName:person02, idCard:220422198311222011, mobile:15311484567, slogan:null
Person05, realName:person02, idCard:220422198311222011, mobile:0, slogan:我愛你中國
Person05, realName:person02, idCard:220422198311222011, mobile:15311484568, slogan:我愛你中國

繼承

object ScalaDemo06 {
  def main(args: Array[String]): Unit = {
    val worker = new Worker("李昊哲", "15311484568", "架構師")
    println(worker)
  }
}

// 主建構函式
class Person06(val realName: String, val mobile: String) {

  println("Person06 主構造器 執行了")

  override def toString: String =
    this.getClass.getSimpleName +
      ", realName:" + realName +
      ", mobile:" + mobile
}

class Worker(realName: String, mobile: String, job: String) extends Person06(realName, mobile) {
  println("Worker 主構造器 執行了")

  override def toString: String =
    this.getClass.getSimpleName +
      ", realName:" + realName +
      ", mobile:" + mobile +
      ", job:" + job
}

抽象類

object ScalaDemo07 {
  def main(args: Array[String]): Unit = {
    val teacher = new Teacher
    teacher.realName = "李昊哲"
    teacher.mobile = "15311484568"
    println(teacher)
    teacher.hi()
  }
}

abstract class Person07() {

  println("Person07 主構造器 執行了")

  var realName: String
  var mobile: String

  def hi(): Unit

  override def toString: String =
    this.getClass.getSimpleName +
      ", realName:" + realName +
      ", mobile:" + mobile
}

class Teacher extends Person07 {
  println("Teacher 主構造器 執行了")

  override def toString: String =
    this.getClass.getSimpleName +
      ", realName:" + realName +
      ", mobile:" + mobile

  override var realName: String = _
  override var mobile: String = _

  override def hi(): Unit = {
    println("接著奏樂 接著舞")
  }
}

伴生類與伴生物件

scala中的類不能定義靜態成員,而代之以定義單例物件來替代
單例物件透過object關鍵字來宣告
單例物件中的所有方法,可以直接透過object單例物件的名字直接來呼叫。
一個單例物件可以繫結在一個類,當單例物件和某個類寫在同一個原始檔且共享一個名字,它們就產生了繫結關係。
此時單例物件稱之為該類的伴生物件,類稱之為該物件的伴生類。

類和它的伴生物件可以互相訪問其私有成員
單例物件不能new,所以也沒有構造引數
可以把單例物件當做java中可能會用到的靜態方法工具類。
作為程式入口的方法必須是靜態的,所以main方法必須處在一個單例物件中,而不能寫在一個類中。

object ScalaDemo08 {
  def main(args: Array[String]): Unit = {
    Food.printMsg()
    new Food().printSlogan()
  }
}

class Food {
  private val msg: String = "hello"
  def printSlogan(): Unit = {
    println(Food.slogan)
  }
}

object Food {
  private val slogan: String = "桃李不言下自成蹊"
  def printMsg(): Unit = {
    println(new Food().msg)
  }
}

apply

object ScalaDemo09 {
  def main(args: Array[String]): Unit = {
    // Drink() 相當於 Drink.apply
    Drink()
    new Drink().apply()
  }
}

class Drink{
  def apply(): Unit = {
    println("class Food 執行...")
  }
}

object Drink {
  def apply(): Unit = {
    println("object Food 執行...")
  }
}

相關文章