ScalaBase

ScalaBase

Scala是将函数式编程思想和面向对象的编程思想结合的一种编程语言

编写scala注意事项:

1、java中的一些写法,scala中同样适用

2、scala中一行代码就是一个语句,分号可加可不加

3、若想运行一个scala代码,需满足:

​ 要有main方法

​ 将class改为object

4、在scala中的class仅代表一个普通的类,object表示一个类的单例对象

特点

  • 多范式
    • 面向对象
    • 函数式编程
  • 兼容Java
    • 类库调用
    • 互操作
  • 语法简洁
    • 代码行短
    • 类型判断
    • 抽象控制
  • 静态类型化
    • 可检验
    • 安全重构
  • 支持并发控制
    • 强计算能力
    • 自定义其他控制结构

变量

/**
     * 定义变量的注意事项:
     * 1、在scala中创建变量需要使用一个关键字:var
     * 2、定义变量的时候,可以不加数据类型,scala会进行自动类型推断
     * 3、变量一旦创建了,数据类型就确定了
     * 4、可以在创建变量的同时,明确给出数据类型
     * 语法: var 变量名:数据类型 = 变量值
     * 5、scala中的基本数据类型的写法和java的不太一样
     * java                       scala
     * byte                        Byte
     * short                       Short
     * int                         Int
     * long                        Long
     * float                       Float
     * double                      Double
     * boolean                     Boolean
     * char                        Char
     */
    //如何创建一个变量
    //1、在scala中创建变量需要使用一个关键字:var
    //创建一个int类型的变量
    var a1 = 10
    println(a1)
    //获取该变量的类型
    println(a1.getClass)
    var a2 = 100
    println(a2)
    var a3 = "hello"
    println(a3)

    //创建一个Int类型的变量a2
    var a4: Int = 100
    println(a4)

常量

/**
     * 常量:在程序运行过程中,其值不能发生改变的量
     * 定义常量的注意事项:
     * 1、定义常量,使用关键字val
     */
    //定义一个Int类型的常量
    val b1: Int = 100
    println(b1)
    val b2 = 200
    println(b2)

字符串

/**
     * 字符串
     * 注意事项:
     * 1、scala中的字符串数据类型和java中的字符串数据类型是一样的,String类
     * 2、可以使用java中String类中的所有方法
     *
     *
     * 数组
     * 1、scala中提供了一个类:Array专门表示数组的类型
     * 2、scala中的数组,和java中的数组一样,也是有索引的,索引也是从0开始的
     * 3、scala中的数组若想通过索引获取元素,得使用小括号
     */
        var s1:String = "hello,world,java,spark,flink"
//    调用String类中的方法,将字符串按照指定分隔符进行切分
        val arr1: Array[String] = s1.split(",")
        println(arr1)
//    获取数组中的第一个元素
        println(arr1(0))
        println(arr1(1))
        println(arr1(2))
        println(arr1(3))
        println(arr1(4))

/**
     * 字符串创建的方式
     */
//    字符串如何表示
//    方式1:使用一对双引号表示
        var s2 = "hello"
        var s2 = "select" +
          "*" +
          "from" +
          "where"
        println(s2)

//	  方式2:使用一对三个双引号
//    当字符串很长且需要换行的时候【写sql的时候】
        var s3 = """hello"""
        var s3 =
        """select
          |*
          |from
          |students
          |where
          |id='1001'
          |""".stripMargin
       println(s3)


/**
     * 字符串格式化的方式
     * 1、和java一样使用 + ,只能是字符串常量之间相加
     * 2、使用java中的类,例如StringBuilder
     * 3、当存在一个序列【数组或迭代器】的时候,调用方法构建一个字符串
     * 4、【在scala中最常用的】 s函数构建字符串
     */
    var s1: String = "hello"
    var s2: String = "world"
    println("hello" + "_" + "world")

    val sb: StringBuilder = new StringBuilder()
    sb.append("hello").append("_").append("world")
    println(sb)

    var s1:String = "hello,world,java,flink,spark"
    val arr1: Array[String] = s1.split(",")
    val s2: String = arr1.mkString("|")
    println(s2)
    println(s"${s1} _ ${s2}")

运算符

/**
     * 运算符,大多数都是函数
     * 注意:scala中没有++和--的运算符
     */
    var a = 3
    var b = 4
    println(s"a+b的值为:${a + b}")
    println(s"a-b的值为:${a - b}")
    println(s"a*b的值为:${a * b}")
    println(s"a/b的值为:${a * 1.0 / b}")
    println(s"a%b的值为:${a % b}")

    //将变量a的值+1
    //    a = a + 1
    //    a++
    a += 1
    println(s"a的值为: ${a}")
    println("=" * 50)

流程控制语句

/**
     * 控制流程语句
     */
    /**
     * if语句
     *
     */
    val sc = new Scanner(System.in)
    println("请输入您的年龄:")
    val age: Int = sc.nextInt()
    if(age>=18){
      println("已经成年!")
    }else{
      println("您还未成年!")
    }


/**
     * for循环
     * scala中的for循环不能写成和java一样的普通for循环或增强for循环
     */
//    val arr1: Array[String] = Array("hello", "world", "java", "hello", "spark", "flink")
//    for(var i:Int = 0;i<arr1.length;i+=1){
//      println(arr1(i))
//    }
//    for(Int i : arr1){
//      println(i)
//	  }

//    scala中的for循环
    for (i <- arr1) {
      println(i)
    }



/**
     * while循环
     */
    var index = 0
    while(index<arr1.length){
      println(arr1(index))
      index+=1
    }
    var index = 0
    do{
      println(arr1(index))
      index+=1
    }while(index<arr1.length)



//    需求:在控制台输出10行hello world
//    实现1:使用while循环
      var i = 10
      while(i>0){
      println("hello world")
      i-=1
      }
//    实现2:使用for循环
      for(i <- 1 to 10){ // [1,10]
        println("hello world")
      }

      for(i <- 1 until 10){  // [1,10)
        println("hello world")
      }

I/O流


import scala.io.{BufferedSource, Source}

object Demo2IO {
  def main(args: Array[String]): Unit = {
    /**
     * 输入流
     */
    //使用java中的类进行读取数据
    //    val br: BufferedReader = new BufferedReader(new FileReader("scala/data/words.txt"))
    //    var line = br.readLine()
    //    while(line!=null){
    //      println(line)
    //      line = br.readLine()
    //    }
    //使用scala中特有的读取文本数据方式
    val bs: BufferedSource = Source.fromFile("scala/data/words.txt") //底层是调用了字节输入流的方式读取数据
    val lines: Iterator[String] = bs.getLines() // 调用BufferedSource类中的getLines方法,得到一个存储所有行数据的迭代器
    //遍历迭代器的第一种方式:调用迭代器中的方法
    while (lines.hasNext){ // 判断下一行是否有数据
      val line: String = lines.next() // 取出一行数据
      println(line)
    }
    //遍历迭代器的第二种方式:使用scala语法中的for循环
    for (line <- lines) {
      println(line)
    }
    /**
     * 注意:scala中没有特殊的输出流语法,只能使用java中输出流
     */
  }
}

函数

/**
 * scala中功能有两种叫法:方法,函数
 * 在class中定义的称之为方法
 * 在object中定义的称之为函数、
 *
 * def: 是scala中定义函数或方法的关键字
 * main:是函数名或方法名
 * args:参数名
 * Array[String]:参数类型
 * Unit:类似于java中的void,表示该函数或方法没有返回值
 * \    = : 后面跟着方法体
 *
 * def main(args: Array[String]): Unit = {
 * }
 */

def main(args: Array[String]): Unit = {
    //注意1:若函数定义在当前的object中,可以使用类名直接调用
        val res1: Int = Demo4Function.add1(100, 200)
        println(res1)

    //注意2:若函数定义在当前的object中,可以直接调用,不需要对象名
        val res2: Int = add1(11, 22)
        println(res2)

    //注意3:函数中可以继续定义函数,为我们后面讲解返回值类型是函数做准备
        def add2(a1: Int, b1: Int): Int = {
          return a1 + b1
        }
    //    //调用必须在定义的后面
        val res3: Int = add2(100, 200)
        println(res3)
    
//注意4:函数不能脱离class或object定义
def add4(a1: Int, b1: Int): Int = {
  return a1 + b1
}
    //注意5: 若调用class类中的方法,必须先创建类的对象
        val d1: Demo1 = new Demo1()
        val res4: Int = d1.show(100, 200)
        println(res4)

        Demo2.show2() //可以的, 因为Demo2是被object修饰的,jvm底层会自动创建一个Demo2对象,名字和类名一致,这里相当于对象调用方法

    val res5: Int = fun1("1000")
    println(res5)

      fun2
      fun3()
  }

//定义格式1: 定义函数,函数特点,只有一个参数和一个返回值
    def fun1(s:String):Int={
      return s.toInt
    }

  //定义格式2: 如果函数中,最后一条语句作为返回值的话,return可以省略不写
    def fun1(s: String): Int = {
      println("开始将字符串s转成Int类型")
      //...
      s.toInt
    }

  //定义格式3: 如果函数中,函数体中只有一条语句,大括号也可以不用写
  def fun1(s: String): Int = s.toInt

  //定义格式4: 如果函数没有参数且没有返回值,小括号也可以不用写,注意,调用的时候,也不能有小括号
  def fun2 = println("好好学习,天天向上!  fun2")
  def fun3() = println("好好学习,天天向上! fun3")

/**
 * scala是基于java封装的语言,所以也具备面向对象的特点,封装,继承,多态
 * 这里基本上都满足java的特点。
 *
 * 注意事项:
 * 1、每一个类必须要有一个主构造方法,在类上面直接定义
 * 2、scala中的类的构造方法,也可以发生重载
 * 3、除了在类上面定义的主构造方法以外,在类中定义的其他this构造方法都属于辅助构造方法
 * 4、辅助构造方法第一句话,必须要调用主构造方法
 * 5、scala类中的方法也可以进行方法重写,但是必须要加上一个关键字 override
 * 6、定义主构造方法的时候,成员变量默认是不允许直接获取的
 * 7、若一个类被object修饰,那么编译过程中会产生两个文件一个带$一个不带,带$的文件中会自动创建一个该类的对象
 * 8、若一个类只是被class修饰,那么编译过程中只会一个对象的class文件,如果要调用对象中的方法,需要自己在程序中new出来。
 */

object Demo7Class {
  def main(args: Array[String]): Unit = {
    //    val s1: Student = new Student()
    //    val s2: Student = new Student()
    //    val s1: Student = new Student("张三", 18)
    //    val s2: Student = new Student()

    val s1: Student = new Student("张三", 18)
    println(s"s1: ${s1}") // 直接打印对象名和java中一样,获取的是当前对象的地址值,默认调用的是父亲中的toString方法

    //    s1.name // 成员变量默认是不允许直接获取的
    //    println(s"姓名:${s1.name}")

    //    s1.name = "李四"
    s1._name = "李四" // 若主构造方法上的变量被var修饰的话,就可以修改成员变量值
    println(s"s1: ${s1}")


  }
}


/**
 * 一个标准类中的三大成员:构造方法,成员变量,成员方法
 *
 * 构造方法:
 * 主构造方法:将成员变量定义在类上,一个类本身就作为一个构造方法。
 * 辅助构造方法:
 */

class Student { // 类的大括号,就看作主构造方法的方法体。
  println("hello world!")
}


/**
 * 主构造方法为:Student(name: String, age: Int)
 */


class Student(var _name: String, _age: Int) {
  //定义成员变量
  def name:String = _name
  var age:Int = _age

  // 辅助无参构造方法
  def this(){
    this("默认姓名",18) // 必须要调用主构造方法
  }

  def setAge(a:Int):Unit={
    age = a
  }

  //重写toString
  override def toString: String = s"姓名:${_name}, 年龄:${_age}"
}

class Student(var _name: String, var _age: Int) {
  // 辅助无参构造方法
  def this() {
    this("默认姓名", 18) // 必须要调用主构造方法
  }

  //重写toString
  override def toString: String = s"姓名:${_name}, 年龄:${_age}"
}
scala中的继承
 注意事项:
   1、子类继承父类的时候,也是使用extends关键字
   2、子类可以继承父类中的变量var或常量val
   3、子类可以重写父类中被val修饰的常量, 父类中var修饰的变量,子类中可以直接改值
   4、多态的调用特点和java中多态一样
   5、scala中的类也只能进行单继承
scala中也具备抽象类的概念

	1、和java一样如果一个方法是抽象方法的话,那么改该方法没有方法体,没有=和{}
	2、和java一样如果一个类中有抽象方法的话,这个类一定要定义成抽象类
	3、当一个具体的类继承抽象类的时候,必须要实现所有的抽象方法
scala中的接口

	1、提供了一个关键字用于定义一个接口 trait
	2、类要实现接口的话,使用extends
	3、一个类可以实现多个接口
	4、如果一个类要实现多个接口,多个接口之间使用with连接

函数式编程

/**
 * 面向对象编程
 * 核心的类型是类,主要的思路将对象在方法中传来传去
 * 方法的参数类型可以是一个类【抽象类,接口】,将来调用时可以传入一个对象在方法中,
 * 方法的返回值类型也可以是一个类【抽象类,接口】,将来调用完方法时得到一个对象。
 *
 *
 * 面向函数式编程
 * 本意就是将函数作为方法或函数的参数类型或返回值
 * 1、函数A是函数B的参数,调用函数B的时候,可以将函数A当作参数传入,可以在函数B的内部使用函数A
 * 2、函数A是函数B的返回值,调用完函数B的时候,可以得到一个函数A。
 *
 * 面向对象编程中,区分什么类型的对象,是由类的名字来区分并决定将来要传入什么对象或返回什么对象
 * 面向函数式编程中,怎么区分函数【或方法】的种类呢?
 * 答:函数是根据参数类型和返回值类型来区分的。
 *
 * 函数fun1:它的参数类型是一个字符串,返回值类型是一个Int类型
 * def show1(s:Student):Unit={
 * ...
 * }
 *
 * def show1(f:String=>Int):Unit={
 * ...
 * }
 *
 * 函数的数据类型:参数类型=>返回值类型
 *
 * 一、将函数作为另一个函数的参数类型传入
 */
object Demo13Function {
  def main(args: Array[String]): Unit = {
    def fun1(s: String): Int = {
      s.toInt + 100
    }
        println(fun1("1000"))

//    函数可以赋值给一个变量
        val a1:String=>Int = fun1
        println(a1("200"))

//    函数作为参数类型传入
        def show1(f:String=>Int):Unit={
          println(f("11"))
        }
        show1(fun1)

    //定义函数的时候,参数列表中,不仅有函数的类型,还有具体的值类型
    def show1(s: String, f: String => Int): Unit = {
      println(f(s))
    }

        def fun2(s:String):Int={
          s.toInt+111
        }
        def fun3(s:String):Int={
          s.toInt+222
        }
        def fun4(s:String):Int={
          s.toInt+333
        }
//    调用方式1:自己定义一个符合类型的函数传入
        show1("200", fun2)
        show1("200", fun3)
        show1("200", fun4)

    //调用方式2:直接在调用时使用lambda表达式
    show1("100", (s: String) => s.toInt + 111)
//    show1("100", (s: String) => s.toInt + 222)
//    show1("100", (s: String) => s.toInt + 333)

    //简化调用方式2写法1,数据类型可以不用写,scala语言会进行自动类型推断
    show1("100", s => s.toInt + 111)

    //简化调用方式2写法2,如果函数的参数只有一个的话,直接使用下划线代替左边的参数进行使用
    show1("100", _.toInt + 111)
  }
}
posted @ 2025-03-26 15:29  Roxan  阅读(40)  评论(0)    收藏  举报