编程语言之scala基础

1.数组Array
1.1定长数组
1.1.1 定义方式
//通过new的方式
val arr1 = new Array [Int] (3) //指定长度为3。Int类型初始化为0
val arr2 = new Array [String] (3) //String类型初始化为null

//通过apply方法
val arr3 = Array(1,“scala”,3,14)
val arr4 = Array.apply(1,“scala”,3,14)
说明:apply方法内部通过new Array [T] ()

1.1.2 通过下标赋值、修改值
//定长数组赋值、修改
arr2(0) = “章子怡”
arr2(1) = “王菲”
arr2(1) = “鞠婧祎”
返回:ArrayBuffer(章子怡, 鞠婧祎, null)

1.1.3 数组转List
//数组转List
val list1: immutable.Seq[String] = arr2.toList
val list2: List[String] = arr2.toList

1.1.4 遍历数组元素
//通过下标取值
for (i <- 0 until arr3.length) {
println(s" i = = i== i=={arr4(i)}")
}

//直接循环出数组元素
for (i <- arr4) {
println(i)
}

1.2变长数组
import scala.collection.mutable.{ArrayBuffer, ListBuffer} //依赖包
1.2.1定义方式
//通过new的方式
val buffer1 = new ArrayBuffer[String] ()
buffer1 += “王祖贤”
buffer1 += “林青霞”

//通过apply方法
val buffer2 = ArrayBuffer(“赵丽颖”,“鞠婧祎”)
val buffer3 = ArrayBuffer.apply(“李一桐”,“周迅”)

1.2.2 删除元素
buffer3.remove(1) //删除下标为1的元素

1.2.3 排序
//排序
val buffer4 = ArrayBuffer(1,3,5,7,6,4,2,0)
val buffer4_1 = buffer4.sortWith(<)
val buffer4_2 = buffer4.sortWith((x,y) => x < y)

2.集合Map
2.1不可变map
2.1.1定义方式
//通过-> 来定义Map或者元组方式
val map1:Map[String,Int] = Map(“鞠婧祎” -> 25, “刘亦菲” -> 31)
val map2 = Map((“杨钰莹”,44),(“邓丽君”,46))

2.1.2 遍历元素
for (i <- map1) {
println(i)
}

for ((k,v) <- map1) {
println(k,v)
}

//迭代循环
for (i <- map1.iterator) {
println(i)
}

//增强循环
map1.foreach(tuple => {
println(tuple._1,tuple._2)
})

2.1.3 取值
val keys = map1.keySet //获取所有key
val values = map1.values //获取所有value
val value1 = map1.getOrElse(“杨紫”,“无此值”) //获取对应key的value

2.2可变map
import scala.collection.{immutable, mutable} //依赖包
2.2.1 定义方式
val mmap = mutable.Map[String, String] () //需要指定泛型
val mmap2 = mutable.Map.empty[String, Int]
val hmap = mutable.HashMap[String,String] () //需要指定泛型
val hmap2 = mutable.HashMap.empty[String, Int]

2.2.2 添加元素
mmap += “杨幂” -> “女”
mmap += (“杨紫” -> “女”, “任嘉伦” -> “男”)
mmap += ((“刘亦菲”, “女”), (“胡歌”, “男”), (“涂磊”, “未知”),(“鞠婧祎”,“女”))

2.2.3 删除元素
mmap -= “刘亦菲”

2.2.4 修改元素
mmap.update(“涂磊”, “男”)

2.2.5 根据key获取值
hmap += ((“杨幂”,“三生三世十里桃花”),(“鞠婧祎”,“叹云夕”),(“胡歌”,“琅琊榜”),(“任嘉伦”,“白蛇传说”),(“杨紫”,“白蛇传说”))
val it: Iterable[String] = mmap.keys
var value: Option[String] = null
it.foreach(key => {
value = hmap.get(key) //一般使用getOrElse(“key值”,“默认值”)
value match {
case None => println(s" k e y = = 未 主 演 电 视 剧 " ) c a s e S o m e ( o t h e r V a l u e ) = > p r i n t l n ( s " key==未主演电视剧") case Some(otherValue) => println(s" key==")caseSome(otherValue)=>println(s"key==$otherValue")
}
})

说明:
默认创建的map为不可变的map, Map() immutable.Map()
如果创建可变的map必须要使用mutable;mutable.MapA,B
可变和不可变的区别:
a 定义使用的关键字不一样
b 不可变的map如果使用 val修饰,则不能修改其值,但是可变的map无论用var或者val修饰都可以修改其值
c 不可变的map在更新其值之后会返回一个新的map,但是可变的map修改其值将修改原map值,返回unit

3.列表List
3.1 不可变List
3.1.1 定义方式
val lis1 = List(“贾静雯”, “安以轩”, “杨幂”, “高圆圆”)

3.1.2 添加元素
val lis2 = lis1 :+ “黎姿” //末尾添加
val lis3 = “张敏” +: lis2 //列表头部添加

3.2 可变List
3.2.1 定义方式
val lbf1: ListBuffer[String] = new ListBuffer[String] ()
val list = mutable.ListBuffer.empty[String]
val list2 = mutable.ListBufferString

3.2.2 添加元素
lbf1 += “飞狐外传”
lbf1 += “雪山飞狐”
lbf2 += “连城诀”
lbf2 += “天龙八部”
lbf2.append(“射雕英雄传”)
lbf2.append(“白马啸西风”)

4.Set
//不可变Set
val set1: Set[String] = Set[String] () //特质,不能new。通过apply方法
val set2: Set[String] = new HashSet[String] () //new 其子类对象

//可变Set
val mset3: mutable.Set[String] = mutable.Set ()
val mset = mutable.Set.empty[String]
val hashSet = new mutable.HashSet[String] ()
val mhset = mutable.HashSet.empty[String]

hashSet += “笑傲江湖”
hashSet.add(“书剑恩仇录”)

5.for过滤器
5.1 函数
//for过滤器函数
val grepFunc = (books: ArrayBuffer[String], grepPattern: String) => {
if (books != null) {
val greps: ArrayBuffer[String] = for {
book <- books
if (book.contains(grepPattern))
} yield book
println(greps)
}
}

5.2 方法
//for过滤器方法
def grep(books: ArrayBuffer[String]): ArrayBuffer[String] = {
var greps: ArrayBuffer[String] = null
if (books != null) {
greps = for {
book <- books
if (book.length == 3)
} yield book
}
greps
}

5.3 测试
val buffer2 = ArrayBuffer[String] ()
buffer2 += (“武林外史”,“绝代双骄”,“楚留香传奇”,“多情剑客无情剑”,“萧十一郎”,“流星蝴蝶剑”,“边城浪子”,
“陆小凤传奇”,“孔雀翎”,“天涯明月刀”,“三少爷的剑”,“圆月弯刀”,“小李飞刀”,“浣花洗剑录”)

5.4 scala中的循环中断

package scalaDemo

import util.control.Breaks._

object CircleBreak {
  def main(args: Array[String]): Unit = {

    //方式1:通过调用break函数实现中断
    var num1 = 0
    breakable {
      while (num1 <= 50) {
        if (num1 % 2 != 0) {
          println(s"num1==$num1")
        }

        if (num1 == 9) {
          println("while循环中断...\r\nfor循环开始...")
          break()
        }
        num1 += 1
      }
    }

    breakable {
      for (num2 <- 1 to 50) {
        if (num2 % 2 == 0) {
          println(s"num2==$num2")
        }
        if (num2 == 10) {
          println("for循环中断...\r\n")
          break()
        }
      }
    }

    //方式2:通过循环守卫实现中断
    var flag = true
    //def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step)
    for (num3 <- Range(1, 10, 2) if flag) {
      if (num3 == 5) {
        flag = false
        println("结束循环...")
      } else {
        println(s"num3==$num3")
      }
    }

    //方式3:通过引入外部变量
    val arr = Array('a','b','c','d','e','f')
    var i = 0
    var elem = ' '
    var tmpf = true
    while ({elem = arr(i); i <= arr.length && tmpf}) {
      if (elem != 'd') {
        println(elem)
      } else {
        println("结束循环...")
        tmpf = false
      }

      i +=1
    }

  }
}

5.5 scala中循环实现continue效果

package scalaDemo

object CircleContinue {
  def main(args: Array[String]): Unit = {
    //方式1:通过循环守卫实现continue效果
    for (i <- 1 to 10 if i % 2 == 0) {
      println(s"i==$i")
    }

    var j = 0
    while (j <= 10) {
      //方式2:通过if表达式实现continue效果
      if (j % 2 != 0) {
        println(s"j==$j")
      }
      j +=1
    }
  }
}

6.scala中的变长参数
//变长参数
def method1(author: String, books: String*): String = {
val buffer = new StringBuffer()
var res: String = “”
if (!author.isEmpty && books != null) {
buffer.append(author + “:”)
for (book <- books) {
buffer.append(book + “|”)
}
val tmpStr = buffer.toString
res = tmpStr.substring(0,tmpStr.length-1)
}
res
}
//测试
val res1 = method1(“古龙”,“武林外史”,“绝代双骄”,“楚留香传奇”,“多情剑客无情剑”,“萧十一郎”,“流星蝴蝶剑”,“边城浪子”)
println(res1)
备注:scala中的变长参数只允许有一个,且必须在末尾

7.类
7.1 内部类
class CircleArea {
private[this] var r: Double = _
private[this] var s: Double = _

def rget: Double = r

def rset(r: Double): Unit = {
this.r = r
}

//圆面积
def getCircleArea: Double = {
this.s = 3.14*Math.sqrt®
s
}

//圆柱体积(内部类可以访问外部类中的属性)
class CylinderVolume {
private[this] var h: Double = _
var v: Double = _ //外部类无法访问内部类中的属性

def hget: Double = h

def hset(h: Double): Unit = {
  this.h = h
}

//体积
def getCylinderVolume: Double = {
  s*h
}

}

//获取内部类
def getInnerCylinderVolume: CylinderVolume = {
val cylinderVolume = new CylinderVolume
cylinderVolume
}
}

object CircleArea {
def main(args: Array[String]): Unit = {
val r: Double = 6
val h: Double = 1
val circleArea = new CircleArea
circleArea.rset®
val s = circleArea.getCircleArea
//内部类不能直接new,需要提供一个方法
val cylinderVolume = circleArea.getInnerCylinderVolume
cylinderVolume.hset(h)
val v = cylinderVolume.getCylinderVolume
println(s"r: $r\r\nh: $h\r\ns: $s\r\nv: $v")
}
}

7.2 主构造器
//主构造器参数用val修饰后,将不能再次赋值
class Demo3(var book: String, var author: String) {

def myMethod1(book: String, author: String): Unit = {
this.book = book
this.author = author
}

override def toString: String = s"书名: $book 作者: $author"
}

object TestMain {
def main(args: Array[String]): Unit = {
val demo1 = new Demo3(“射雕英雄传”,“金庸”)
println(demo1)
demo1.myMethod1(“楚留香传奇”,“古龙”)
println(demo1)
}
}

package scalaDemo.chapter.chapter02

object Test_Variable {
  def main(args: Array[String]): Unit = {
    val stu1 = new Student01("赵敏", 20, "清华大学")

    //1.Student01对象中的name属性访问不到,没有用val或var修饰
    //2.由于age被val修饰,值不可修改。而school被var修饰,值可以修改
    // stu1.age = 18
    
    stu1.school = "北京大学"
    stu1.stuInfo

    /**
      * 总结:主构造器中name、age、school都会被编译成私有成员变量和构造方法
      * private final String name;
      * private final int age;
      * private String school;
      *
      * public Student01(String name, int age, String school) {}
      *
      * val修饰的变量会生成公有的类似java中的"get"方法
      * public int age() {
      *   return this.age;
      * }
      *
      * val修饰的变量会生成公有的类似java中的"get"方法和 "set"方法
      * scala中用变量名()和变量名_$eq()来表示
      * public String school() {
      *   return this.school;
      * }
      *
      * public void school_$eq(String x$1) {
      *     this.school = x$1;
      * }
      *
      *
      **/
  }
}

class Student01(name: String, val age: Int, var school: String) {
  def stuInfo = {
    println(s"name=$name age=$age school=$school")
  }
}


7.3 辅助构造器

//主构造器private修饰,仅限于当前类、伴生对象访问;private[this]表示仅限于当前类访问
class Demo5 private (var author: String, var bookName: String) {
private var star: String = _
private[this] var fan: String = _ //关键字this,伴生对象无法访问该属性

//辅助构造器1
def this(author: String, bookName: String,star: String) = {
this(author,bookName) //调用主构造器
this.star = star
}

//辅助构造器2 (方式1)
// def this(author: String, bookName: String,star: String,fan: String) = {
// this(author,bookName)
// this.star = star
// this.fan = fan
// }

//辅助构造器2 (方式2)
def this(author: String, bookName: String,star: String,fan: String) = {
this(author,bookName,star) //调用辅助构造器1
this.fan = fan
}

override def toString: String = {
s"author: $author\r\nbookName: $bookName\r\nstar: $star\r\nfan: $fan"
}
}

object Demo5 {
def main(args: Array[String]): Unit = {
//主构造器创建对象
val demo1 = new Demo5(“古龙”,“小李飞刀”)
//辅助构造1器创建对象
val demo2 = new Demo5(“古龙”,“小李飞刀”,“萧蔷”)
//辅助构造器2创建对象
val demo3 = new Demo5(“古龙”,“小李飞刀”,“萧蔷”,“高晓松”)

println(demo1)
println(demo2)
println(demo3)

}
}

7.4 自定义apply方法

//主构造器private修饰,仅限于当前类、伴生对象访问;private[this]表示仅限于当前类访问
class Demo6 private (var author: String, var bookName: String) {
private var star: String = _
private[this] var fan: String = _ //关键字this,伴生对象无法访问该属性

//辅助构造器1
def this(author: String, bookName: String,star: String) = {
this(author,bookName) //调用主构造器
this.star = star
}

//辅助构造器2 (方式1)
// def this(author: String, bookName: String,star: String,fan: String) = {
// this(author,bookName)
// this.star = star
// this.fan = fan
// }

//辅助构造器2 (方式2)
def this(author: String, bookName: String,star: String,fan: String) = {
this(author,bookName,star) //调用辅助构造器1
this.fan = fan
}

override def toString: String = {
s"author: $author\r\nbookName: $bookName\r\nstar: $star\r\nfan: $fan"
}
}

//自定义apply方法
object Demo6 {
//定长参数
def apply(author: String, bookName: String): Demo6 = {
val demo = new Demo6(author,bookName)
demo
}

//定长参数
def apply(author: String, bookName: String, star: String): Demo6 = {
val demo = new Demo6(author,bookName,star)
demo
}

//变长参数
def apply(author: String, str: String*): Demo6 = {
var demo: Demo6 = null
if (!str.isEmpty && str != null) {
demo = new Demo6(author,str(0),str(1),str(2))
}
demo
}
}

object Demo6Test {
def main(args: Array[String]): Unit = {
Array(1,2)
val demo1 = Demo6(“古龙”,“小李飞刀”)
val demo2 = Demo6(“古龙”,“小李飞刀”,“萧蔷”)
val demo3 = Demo6(“古龙”,“小李飞刀”,“萧蔷”,“高晓松”)

println(demo1)
println(demo2)
println(demo3)

}
}

7.5 setter和getter方法

package scalaDemo

object ClassTest {
  def main(args: Array[String]): Unit = {
    val person = new Person()
    person.name = "鞠婧祎"  //person.name_$eq("鞠婧祎")
    person.gender = "女" //person.gender_$eq("女")
   // person.age = 26   //person.age_$eq(26)
  }
}
class Person {
  private val privateDescription: String = "私有属性-人类" //生成的字节码文件中,只有私有的getter方法--pirvate String privateDescription()
  val publicDescription: String = "公有属性-动物" //生成的字节码文件中,只有公有的getter方法--public String publicDescription()
  var name: String = _  //var修饰的变量,编译成的字节码文件中,既有setter方法又有getter方法
protected var gender1: String = _ //当前类及其子类对象可以访问
protected[scalaDemo] var gender2: String = _ //String和引用类型的变量,使用"_"初始化时全部为null
  private var age: Int = _  //val修饰的属性,字节码文件只有getter方法,而var修饰的属性,字节码文件既有setter又有getter方法
}
/*
public class Person {
  private final String privateDescription = ";

  private String privateDescription() {
    return this.privateDescription;
  }

  private final String publicDescription = ";

  private String name;

  private String gender;

  private int age;

  public String publicDescription() {
    return this.publicDescription;
  }

  public String name() {
    return this.name;
  }

  public void name_$eq(String x$1) {
    this.name = x$1;
  }

  public String gender() {
    return this.gender;
  }

  public void gender_$eq(String x$1) {
    this.gender = x$1;
  }

  private int age() {
    return this.age;
  }

  private void age_$eq(int x$1) {
    this.age = x$1;
  }
}
*/

class Demo4 {
private val reader: String = “张韶涵”
private var bookName: String = _ //当前类及其伴生对象可以访问
private[this] var author: String = _ //this表示只能在当前类中访问,伴生对象无法访问

//getter方法和setter方法
def bookname: String = bookName

def bookname_=(bookName: String): Unit = {
this.bookName = bookName
}

def authors: String = author

def authors_=(author: String): Unit = {
this.author = author
}
}

object Demo4Test {
def main(args: Array[String]): Unit = {
val class1 = new Demo4
class1.bookname_=(“西游记”)
class1.authors_=(“吴承恩”)
println(class1.bookname)
println(class1.authors)

}
}
说明:
1.scala中是没有getter和setter说法的,当成员变量用private、private[this]等修饰时,
可以提供一对方法,如:method、method_=来替代getter、setter方法

7.6 继承及多态
import scala.collection.mutable.ArrayBuffer
import scala.util.Random

abstract class Animals {
var name: String = _
var age: Int = _
var sex: String = _

def action: String
}

class Persion extends Animals {

private var university: String = _

def this(name: String, age: Int, sex: String) = {
this()
this.name = name
this.age = age
this.sex = sex
}

def this(name: String, age: Int, sex: String, university: String) = {
this(name, age, sex)
this.university = university
}

override def action: String = {
s"name: $nameage: $agesex: $sexuniversity: $universityaction: 喜欢看书、玩游戏、恋爱…"
}

override def toString: String = {
s"name: $nameage: $agesex: $sex**university: $university"
}
}

class Dog extends Animals {
private var food: String = _

def this(name: String, age: Int, sex: String) = {
this()
this.name = name
this.age = age
this.sex = sex
}

def this(name: String, age: Int, sex: String, food: String) = {
this(name, age, sex)
this.food = food
}

override def action: String = {
s"name: $nameage: $agesex: $sexfood: $foodaction: 喜欢卖萌、奔跑、啃骨头…"
}

override def toString: String = s"name: $nameage: $agesex: $sex**food: $food"
}

class Bird extends Animals {
private var flyHigh: Double = _

def this(name: String, age: Int, sex: String) = {
this()
this.name = name
this.age = age
this.sex = sex
}

def this(name: String, age: Int, sex: String, flyHigh: Double) = {
this(name, age, sex)
this.flyHigh = flyHigh
}

override def action: String = {
s"name: $nameage: $agesex: $sexflyHigh: $flyHighaction: 喜欢翱翔、高飞、叽叽喳喳…"
}

override def toString: String = s"name: $nameage: $agesex: $sex**flyHigh: $flyHigh"
}

object ExtendsDemo {
def main(args: Array[String]): Unit = {
val persion: Animals = new Persion(“人类”, 100, “female”, “清华大学”)
val dog = new Dog(“狗类”, 10, “male”, “骨头”)
val bird = new Bird(“鸟类”, 6, “female”, 999)
val buffer: ArrayBuffer[Animals] = new ArrayBuffer
buffer += (persion, dog, bird)
println(buffer)
//多态。父类引用指向子类对象
val animals: Animals = buffer(Random.nextInt(buffer.length))
println(animalAction(animals))
}

//定义一个方法
def animalAction(animal: Animals): String = {
animal.action //实际调用子类中的方法
}
}

7.7 类型判断和类型转换
import scala.collection.mutable.ListBuffer
import scala.util.Random

abstract class Animal {
var name: String = _
var age: Int = _

def action: String
}

class Persion2(var sex: String) extends Animal {
private var favoriteStar: String = _

def this(name: String,age: Int,sex: String) = {
this(sex)
this.name = name
this.age = age
}

def this(name: String,age: Int,sex: String,favoriteStar: String) = {
this(name,age,sex)
this.favoriteStar = favoriteStar
}

def persionMethod: Unit = {
println(“Persion类:”+this.getClass)
}

override def action: String = s"喜欢看书、玩游戏、恋爱…"

override def toString = s"姓名: n a m e ∣ 年 龄 : name|年龄: nameage|性别: s e x ∣ 最 喜 欢 的 明 星 : sex|最喜欢的明星: sexfavoriteStar"
}

class Bird2(var sex: String) extends Animal {
var flyHigh: Double = _

def this(name: String,age: Int,sex: String) = {
this(sex)
this.name = name
this.age = age
}

def this(name: String,age: Int,sex: String,flyHigh: Double) = {
this(name,age,sex)
this.flyHigh = flyHigh
}

def birdMethod: Unit = {
println(“Bird类:”+this.getClass)
}

override def action: String = s"喜欢翱翔、高飞、叽叽喳喳…"

override def toString = s"姓名: n a m e ∣ 年 龄 : name|年龄: nameage|性别: s e x ∣ 飞 翔 高 度 : sex|飞翔高度: sexflyHigh"
}

object ExtendsDemo2 {
def main(args: Array[String]): Unit = {
val persion = new Persion2(“郭敬明”,30,“male”,“杨幂”)
val bird = new Bird2(“白鹭”,2,“female”,999)

val buffer: ListBuffer[Animal] = new ListBuffer[Animal]
buffer += (persion,bird)
println(buffer)
println(classOf[Persion2])
println(classOf[Bird2])

instanceOfMethod1(buffer(Random.nextInt(buffer.length)))
instanceOfMethod2(buffer(Random.nextInt(buffer.length)))

}

//判断一个类是否为指定类及其子类对象。该方法不能精确判断
def instanceOfMethod1(animal: Animal) = {
if(animal.isInstanceOf[Persion2]) {
val persion = animal.asInstanceOf[Persion2]
persion.persionMethod
} else if (animal.isInstanceOf[Bird2]) {
val bird = animal.asInstanceOf[Bird2]
bird.birdMethod
} else {
println(“其他类型”)
}
}
//可以精确判断
def instanceOfMethod2(animal: Animal) = {
if (animal.getClass == classOf[Persion2]) {
val persion = animal.asInstanceOf[Persion2]
persion.persionMethod
} else if (animal.getClass == classOf[Bird2]) {
val bird = animal.asInstanceOf[Bird2]
bird.birdMethod
} else {
println(“其他类型”)
}
}
}

7.8 样例类
case class Teacher(name: String, age: Int)

case class Student(name: String, age: Int)

object Stranger

object CaseClassTest {
def main(args: Array[String]): Unit = {
val teacher1 = Teacher(“张三”,33)
val teacher2 = Teacher(“李四”,26)

val student1 = Student("小明",9)
val student2 = Student("小红",19)

val stranger1 = Stranger

val arr = Array(teacher1,teacher2,student1,student2,stranger1)

for (person <- arr) {
  println(matchCase(person))
}

}

def matchCase(person: AnyRef) = {
person match {
case Teacher(name,age) => s"name= n a m e ∣ a g e = name|age= nameage=age 允许教师进入…"
case Student(name,age) => {
if (age < 18)
s"name= n a m e ∣ a g e = name|age= nameage=age 允许未成年学生进入…"
else
s"name= n a m e ∣ a g e = name|age= nameage=age 允许成年学生进入…"
}
case Stranger => s"禁止陌生人进入!!!"
case _ => s"错误类型匹配!!!"
}
}
}
说明:
case类是一种特殊的类,它们经过优化以被用于模式匹配
当定义一个类时,如果在class关键字前加上case关键字,则该类称为case类
Scala为case类自动重载了许多实用的方法,包括toString、equals和hashcode方法
Scala为每一个case类自动生成一个伴生对象,其包括模板代码1个apply方法,因此,实例化case类的时候无需使用new关键字。和1个unapply方法,该方法包括一个类型为伴生类的参数返回的结果是Option类型,对应的类型参数是N元组,N是伴生类中主构造器参数的个数。Unapply方法用于对对象进行解构操作,在case类模式匹配中,该方法被自动调用,并将待匹配的对象作为参数传递给它。

7.9 特质
trait UsbDisk {
var usbDiskType: String

def usbFunc: String
}

trait Mouse {
var mouseType: String

def mouseFunc: String
}

abstract class Computer {
var brand: String
var price: String
var madeIn: String

def permitGames: String
}

class ThinkPad(var optionSystem: String) extends Computer with UsbDisk with Mouse {

override var brand: String = _
override var price: String = _
override var madeIn: String = _
override var usbDiskType: String = _
override var mouseType: String = _

def this(brand: String,price: String,madeIn: String,os: String) = {
this(os)
this.brand = brand
this.price = price
this.madeIn = madeIn
this.optionSystem = os
}

def this(brand: String,price: String,madeIn: String,os: String,usbDiskType: String) = {
this(brand,price,madeIn,os)
this.usbDiskType = usbDiskType
}

def this(brand: String,price: String,madeIn: String,os: String,usbDiskType: String,mouseType: String) = {
this(brand,price,madeIn,os,usbDiskType)
this.mouseType = mouseType
}

override def permitGames: String = s"绝地求生、英雄联盟、炉石传说…"

override def usbFunc: String = s"U盘用来备份游戏数据…"

override def mouseFunc: String = s"鼠标用来操作人物的移动方向…"

override def toString: String = s"[{电脑|品牌: b r a n d , 产 地 : brand, 产地: brand,madeIn, 操作系统: o p t i o n S y s t e m , 价 格 : optionSystem, 价格: optionSystem,price},{U盘|类型:KaTeX parse error: Expected 'EOF', got '}' at position 12: usbDiskType}̲,{鼠标|类型:mouseType}]"
}

object ExtendsDemo3 {
def main(args: Array[String]): Unit = {
val computer1 = new ThinkPad(“thinkPadE480”,“6666RMB”,“China”,“Win10”)
val computer2 = new ThinkPad(“thinkPadE480”,“6666RMB”,“China”,“Win10”,“西部数据”,“罗技”)
println(computer1)
println(computer2)
println(computer2.permitGames)
println(computer2.usbFunc)
println(computer2.mouseFunc)
}
}
说明:
定义关键字trait。特质类似于java中的接口,java中实现接口关键字"implements",scala中使用"with",如class A extends classB with traitC with traitD …

7.10 抽象类

package scalaDemo.abstractDemo.Demo01

abstract class Animal01 {
  var name: String //抽象属性
  var sex: String
  val name2 = "Animal01" //普通属性

  def describ(): String  //抽象方法
  def action()  //抽象方法

  /**
   * @Author: qwerdf@QAQ
   * @Description:
    * 总结:
    * 抽象类不能被实例化,可以通过创建匿名子类对象来实现
    * 抽象类不一定有abstract方法,但是含有抽象方法或抽象属性的一定是抽象类
    * scala中抽象方法不能用abstract标记,定义方式:def temp()
    * 如果一个类继承了抽象类,则必须实现抽象类的所以抽象方法和抽象属性,除非它自己也声明为abstract类
    * 抽象方法和抽象属性不能使用private、final来修饰,因为这些关键字都是和重写/实现相违背的
    * 抽象类可以有实现的方法
    * 子类重写抽象方法不需要override,也可以加上
   * @Date: 2021/3/14
   * @Param null:
   * @return: null
   **/

}

package scalaDemo.abstractDemo.Demo01

object AnimalTest01 {
  def main(args: Array[String]): Unit = {
    //临时创建一个匿名子类
    val dog = new Animal01 {
      override var name: String = "dog"
      override var sex: String = "雌性"

      override def describ(): String = {
        s"name: $name\nsex: $sex"
      }

      override def action(): Unit = {
        println("正在追赶小偷...")
      }
    }

    val cat = new Animal01 {
      override var name: String = "cat"
      override var sex: String = "雄性"

      override def describ(): String = {
        s"name: $name\nsex: $sex"
      }

      override def action(): Unit = {
        println("正在抓老鼠...")
      }
    }

    println(dog.describ())
    dog.action()

    println(cat.describ())
    cat.action()
  }

}

8.方法和函数
import scala.collection.mutable
import scala.collection.mutable.{ArrayBuffer, ListBuffer}

object FuncAndMethod {
def main(args: Array[String]): Unit = {
//定义一个函数
val fun1: (Int,Int) => Int = (x,y) => x + y
val fun2 = (x:Int, y:Int) => x + y
val fun2_2 = (x: Int) => x //入参只有一个时,括号不能少
val fun3: () => String = () => “飞雪连天射白鹿”

println(fun3()) //参数列表为空时,调用fun3()括号不能省略
method5(999999999) //方法中参数列表为空可以省略括号

method2("笑书神侠倚碧鸳")

val hmap = new mutable.HashMap[String,ArrayBuffer[String]]()
val buffer1 = ArrayBuffer[String]()
val buffer2 = ArrayBuffer[String]()
buffer1 += "飞狐外传"
buffer1 += "飞狐外传"
buffer1 += "雪山飞狐"
buffer1 += "连城诀"
buffer1 += "天龙八部"
buffer1 += "射雕英雄传"
buffer1 += "白马啸西风"
buffer1 += "鹿鼎记"
buffer1 += "笑傲江湖"
buffer1 += "书剑恩仇录"
buffer1 += "神雕侠侣"
buffer1 += "侠客行"
buffer1 += "倚天剑"
buffer1 += "碧血剑"
buffer1 += "鸳鸯刀"
buffer2 += ("武林外史","绝代双骄","楚留香传奇","多情剑客无情剑","萧十一郎","流星蝴蝶剑","边城浪子",
            "陆小凤传奇","孔雀翎","天涯明月刀","三少爷的剑","圆月弯刀","小李飞刀","浣花洗剑录")
hmap += ("金庸" -> buffer1,("古龙",buffer2))
println(hmap)

val res1 = method3("神雕侠侣",hmap)
val res2 = method3("流星蝴蝶剑",hmap)
val res3 = method3("三国演义",hmap)
println(res1)
println(res2)
println(res3)



val res4 = method4("小李飞刀",hmap,fun4)
val res5 = method4("神雕侠侣",hmap,fun4)
val res6 = method4("西游记",hmap,fun4)
println(res4)
println(res5)
println(res6)

val grep1: ArrayBuffer[String] = grep(buffer1)
println(grep1)

//for过滤器函数
val grepFunc = (books: ArrayBuffer[String], grepPattern: String) => {
  if (books != null) {
    val greps: ArrayBuffer[String] = for {
      book <- books
      if (book.contains(grepPattern))
    } yield book
    println(greps)
  }
}

grepFunc(buffer1,"剑")

}

//for过滤器方法
def grep(books: ArrayBuffer[String]): ArrayBuffer[String] = {
var greps: ArrayBuffer[String] = null
if (books != null) {
greps = for {
book <- books
if (book.length == 3)
} yield book
}
greps
}

//定义一个方法
def method1(x:Int,y:Int): Int = {
x + y
}

def method2(str: String): Unit = {
if (!str.isEmpty && str != null) {
println(str)
}
}

def method3(bookName: String, bookStore: mutable.Map[String,ArrayBuffer[String]]): String = {
var tmp_author: String = “未知作者”
if (!bookName.isEmpty || bookName != null) {
for (map <- bookStore) {
val author = map._1
val bookArray = map._2
if (bookArray.contains(bookName)) {
tmp_author=author
}
}
}
tmp_author
}

def method4(bookName: String, bookStore: mutable.Map[String,ArrayBuffer[String]],fun: (String, mutable.Map[String,ArrayBuffer[String]]) => String) : String = {
val value = fun(bookName,bookStore)
value
}

val fun4: (String,mutable.Map[String,ArrayBuffer[String]]) => String = (bookName,bookStore) => {
var tmp_author: String = “未知作者”
if (!bookName.isEmpty || bookName != null) {
for (map <- bookStore) {
val author = map._1
val bookArray = map._2
if (bookArray.contains(bookName)) {
tmp_author=author
}
}
}
tmp_author
}

def method5(f: => Int) = {
println(f)
}
}

9.偏函数
object PartialFunc {
def main(args: Array[String]): Unit = {
val array = Array(‘a’,5,2f,1314D,false,“偏函数”)
for (arr <- array) {
println(matchCase(arr))
println(partitionFunc(arr))
}
}

def matchCase(element: Any) = {
element match {
case a: Char => s"char类型 a " c a s e a : I n t = > s " i n t 类 型 a" case a: Int => s"int类型 a"casea:Int=>s"inta"
case a: Long => s"Long类型 a " c a s e a : F l o a t = > s " f l o a t 类 型 a" case a: Float => s"float类型 a"casea:Float=>s"floata"
case a: Double => s"double类型 a " c a s e a : B o o l e a n = > s " 布 尔 类 型 a" case a: Boolean => s"布尔类型 a"casea:Boolean=>s"a"
case b: String => s"string类型$b"
case _ => s"未匹配到…"
}
}

//偏函数定义
def partitionFunc: PartialFunction[Any, String] = {
case a: Char => s"char类型 a " c a s e a : I n t = > s " i n t 类 型 a" case a: Int => s"int类型 a"casea:Int=>s"inta"
case a: Long => s"Long类型 a " c a s e a : F l o a t = > s " f l o a t 类 型 a" case a: Float => s"float类型 a"casea:Float=>s"floata"
case a: Double => s"double类型 a " c a s e a : B o o l e a n = > s " 布 尔 类 型 a" case a: Boolean => s"布尔类型 a"casea:Boolean=>s"a"
case b: String => s"string类型$b"
case _ => s"未匹配到…"
}
}
说明:
没有match匹配的一组case语句,常用于输入模式匹配。
PartialFunction[A,B] —A表示输入类型,B表示输出类型

10.泛型(方法、类)
abstract class Persion4 {
var name: String
var age: Int

def work: Unit
}

class Teacher4(var salary: Double) extends Persion4 {
override var name: String = _
override var age: Int = _

def this(salary: Double, name: String, age: Int) = {
this(salary)
this.name = name
this.age = age
}

override def work: Unit = println(“教书育人…”)

def getTeacherInfo: String = {
s"姓名: n a m e 年 龄 : name 年龄: nameage 工资:$salary"
}

override def toString = s"Teacher($name, $age, $salary)"
}

//类添加泛型
class Student4[T] (var chineseScore: T, var mathScore: T, var englishScore: T, var comprehensiveScore: T) extends Persion4 {
override var name: String = _
override var age: Int = _

def this(name: String, age: Int, chinese: T, math: T, english: T, comprehensive: T) = {
this(chinese,math,english,comprehensive)
this.name = name
this.age = age
}

override def work: Unit = println(“遨游知识的海洋,为中华崛起而奋斗…”)

def getStudentInfo: String = {
s"姓名: n a m e 年 龄 : name 年龄: nameage 成绩:[ c h i n e s e S c o r e , chineseScore, chineseScore,mathScore, e n g l i s h S c o r e , englishScore, englishScore,comprehensiveScore]"
}

override def toString = s"Student($name, $age, c h i n e s e S c o r e , chineseScore, chineseScore,mathScore, e n g l i s h S c o r e , englishScore, englishScore,comprehensiveScore)"
}

object GenericType {
def main(args: Array[String]): Unit = {
val student1 = new Student4Int
val teacher1 = new Teacher4(6666D,“小马哥”,27)

val arr = Array(student1,teacher1)

for (per <- arr) {
  val info = getInfo(per)
  println(info)
}

}

//方法添加泛型
def getInfo[T](persion: T): String = {
if (persion.getClass == classOf[Student4[Int]]) {
val student = persion.asInstanceOf[Student4[Int]]
student.getStudentInfo
} else if (persion.getClass == classOf[Teacher4]) {
val teacher = persion.asInstanceOf[Teacher4]
teacher.getTeacherInfo
} else s"其他类型…"
}
}

11.上边界和下边界
abstract class ElecGoods {
var categary: String
var brand: String
var model: String

def function: String
}

class Pad extends ElecGoods {
var madeIn: String = _
override var categary: String = _
override var brand: String = _
override var model: String = _

def this(madeIn: String, categary: String, brand: String, model: String) = {
this()
this.categary = categary
this.brand = brand
this.model = model
this.madeIn = madeIn
}

override def function: String = {
s"电影、听音乐、玩游戏…"
}

override def toString = s"Phone($categary, $brand, $model, $madeIn)"
}

class Phone extends ElecGoods {
var madeIn: String = _
override var categary: String = _
override var brand: String = _
override var model: String = _

def this(madeIn: String, categary: String, brand: String, model: String) = {
this()
this.categary = categary
this.brand = brand
this.model = model
}

override def function: String = {
s"通话、听音乐、玩游戏…"
}

override def toString = s"Phone($categary, $brand, $model, $madeIn)"
}

class HuaWeiPhone(var detailModel: String) extends Phone {
private var price: Double = _

def this(categary: String, brand: String, model: String, madeIn: String, detailModel: String) = {
this(detailModel)
this.categary = categary
this.brand = brand
this.model = model
this.madeIn = madeIn
}

def this(categary: String, brand: String, model: String, madeIn: String, detailModel: String, price: Double) = {
this(categary,brand,model,madeIn,detailModel)
this.price = price
}

override def toString = s"HuaWeiPhone($categary, $brand, $model, $madeIn, $detailModel, $price)"
}

class Iphone(var detailModel: String) extends Phone {
private var price: Double = _

def this(categary: String, brand: String, model: String, madeIn: String, detailModel: String) = {
this(detailModel)
this.categary = categary
this.brand = brand
this.model = model
this.madeIn = madeIn
}

def this(categary: String, brand: String, model: String, madeIn: String, detailModel: String, price: Double) = {
this(categary,brand,model,madeIn,detailModel)
this.price = price
}

override def toString = s"Iphone($categary, $brand, $model, $madeIn, $detailModel, $price)"
}

object BoundType {
def main(args: Array[String]): Unit = {
val pad = new Pad(“USA”,“平板电脑”,“苹果”,“ipad”)
val phone = new Phone(“China”,“5G手机”,“华为”,“Mate30”)
val huaWeiPhone = new HuaWeiPhone(“5G手机”,“华为”,“Mate30”,“China”,“Mate30_Pro_8G”,6399)
val iphone = new Iphone(“5G手机”,“苹果”,“iphoneSE”,“USA”,“iphoneSE2_4G”,2799)

upBoundMethod[Phone](huaWeiPhone)
upBoundMethod[Phone](iphone)
//upBoundMethod[Phone](pad)   //编译提示:方法入参类型不匹配,应该为泛型Phone的类型或者子类
//upBoundMethod[ElecGoods](phone) //泛型错误,当前上边界值为Phone类型,泛型A应该为Phone类、HuaWeiPhone类、Iphone类

downBoundMethod[Phone](huaWeiPhone)
downBoundMethod[Phone](iphone)

// downBoundMethodPhone //编译提示:方法入参类型不匹配,应该为泛型Phone的类型或者子类
downBoundMethodHuaWeiPhone //泛型错误,当前下边界值为Phone类型,泛型B应该为Phone类、ElecGoods类
}

//上边界 A类型为Phone类及其子类,而该方法入参类型为A类型及其A类型的子类对象
def upBoundMethod [A <: Phone] (elecGoods: A): Unit = {
if (elecGoods.getClass == classOf[HuaWeiPhone]) {
val huaWeiPhone = elecGoods.asInstanceOf[HuaWeiPhone]
println(huaWeiPhone)
} else if (elecGoods.getClass == classOf[Iphone]) {
val iphone = elecGoods.asInstanceOf[Iphone]
println(iphone)
}
}

//下边界 B类型为Phone类及其父类,而该方法入参类型为B类型及其B类型的子类对象,因为B类型的子类不仅仅只有Phone一个
def downBoundMethod[B >: Phone](elecGoods: B): Unit = {
if (elecGoods.isInstanceOf[Phone]) {
val phone = elecGoods.asInstanceOf[Phone]
println(phone)
}
}

}

12.隐式转换之参数、方法、类
12.1隐式参数

package scalaDemo.implicitDemo.demo01

object ImplicitValDemo01 {

  implicit val name = "tom"
  implicit val age = 18
  def main(args: Array[String]): Unit = {
    implicitFun01
    implicitFun02("sunny")
    implicitFun03//运行报错
  }

  def implicitFun01(implicit name: String = "jack") = {
    println(s"fun01:my name is $name")
  }

  def implicitFun02(implicit name: String = "jack") = {
    println(s"fun01:my name is $name")
  }

  def implicitFun03(implicit score: Double) = {
    println(s"fun01:my score is $score")
  }
  /**
   * @Author: qwerdf@QAQ
   * @Description:
    * 总结:
    *      1.隐式值优先级:传值 > 隐式值 > 默认值
    *      2.隐式值匹配时不能有二义性
    *      3.如果调用方法时,传值、隐式值、默认值都没有,程序会报错
   * @Date: 2021/3/14
   * @Param null:
   * @return: null
   **/

}

12.2隐式方法
object ImplictTransformationFunc {
def main(args: Array[String]): Unit = {
import CurrencyTypeTransformArea._
val rmb = new RMB()
//寻找隐式区域,调用隐式方法并将rmb作为参数传入获取CurrencyType对象,即currencyTypeTransform(rmb).toRMB

val rmbInfo = rmb.toRMB(520) 
println(rmbInfo)


val dollar = new Dollar()
val dollarInfo = dollar.toDollar(520)
println(dollarInfo)

}
}

//隐式区域
object CurrencyTypeTransformArea {
implicit def currencyTypeTransform(currencyType: Currency): CurrencyType = {
new CurrencyType
}
}

class CurrencyType {
def toRMB(price: Double): RMB = {
RMB(price)
}

def toDollar(price: Double): Dollar = {
Dollar(price)
}
}

class Currency {}

class RMB extends Currency {
var price: Double = _
private val logo: String = “RMB”

def this(price: Double) = {
this()
this.price = price
}

override def toString = s" p r i c e price pricelogo"
}

object RMB {
def apply(price: Double): RMB = new RMB(price)
}

class Dollar extends Currency {
var price: Double = _
private val logo: String = “$”

def this(price: Double) = {
this()
this.price = price
}

override def toString = s" p r i c e price pricelogo"
}

object Dollar {
def apply(price: Double): Dollar = new Dollar(price)
}

12.3隐式类

package scalaDemo.implicitDemo.demo02

object ImplicitClassDemo01 {

  implicit class DataBaseFun01(val mySql: Mysql) {
    def insert(): String = {
      s"insert..."
    }
  }

  def main(args: Array[String]): Unit = {
    val mysql = new Mysql
    println(mysql.insert())
  }
}

class Mysql {
  val dname: String = "mysql"

  def dbState = {
    s"mysql is running..."
  }

  /**
   * @Author: qwerdf@QAQ
   * @Description:
    * 总结:
    *     1.隐式类的构造参数有且只能有一个
    *     2.隐式类必须定义在类、伴生对象、包对象里面,不能是顶级的objects
    *     3.隐式类不能是case class
    *     4.作用域内不能有同名标识符,否则编译器无法识别
   * @Date: 2021/3/14
   * @Param null:
   * @return: null
   **/

}

需要一个主构造器,且参数只能有一个;
隐式类必须定义在类或伴生对象中…
object ImplictTransformationFunc {
//隐式类
implicit class CurrencyType2(var currency: Currency) {
def toRMB(price: Double): RMB = {
RMB(price)
}

def toDollar(price: Double): Dollar = {
  Dollar(price)
}

}

def main(args: Array[String]): Unit = {
//方式1:隐式方法测试
// import CurrencyTypeTransformArea._ //导入隐式方法区域
// val rmb = new RMB()
// //寻找隐式区域,调用隐式方法并将rmb作为参数传入获取CurrencyType对象,即currencyTypeTransform(rmb).toRMB
// val rmbInfo = rmb.toRMB(520)
// println(rmbInfo)

//方式2:隐式类测试
val dollar = new Dollar()
//寻找隐式类,然后将dollar作为构造器参数进行实例化,即CurrencyType2(dollar).toDollar
val dollarInfo = dollar.toDollar(1314)
println(dollarInfo)

}
}

//隐式区域
object CurrencyTypeTransformArea {
implicit def currencyTypeTransform(currencyType: Currency): CurrencyType = {
new CurrencyType
}
}

class CurrencyType {
def toRMB(price: Double): RMB = {
RMB(price)
}

def toDollar(price: Double): Dollar = {
Dollar(price)
}
}

class Currency {}

class RMB extends Currency {
var price: Double = _
private val logo: String = “RMB”

def this(price: Double) = {
this()
this.price = price
}

override def toString = s" p r i c e price pricelogo"
}

object RMB {
def apply(price: Double): RMB = new RMB(price)
}

class Dollar extends Currency {
var price: Double = _
private val logo: String = “$”

def this(price: Double) = {
this()
this.price = price
}

override def toString = s" p r i c e price pricelogo"
}

object Dollar {
def apply(price: Double): Dollar = new Dollar(price)
}

隐式转换场景:
当方法中的参数类型与目标类型不一致时候,如:
def method1(age: Int) = {}
method1(66.5) //传入类型不匹配,要想编译通过,可使用隐式转换。
当对象调用所在类中没有该方法或成员时,编译器会自动将对象进行隐式转换,转变为含有该方法或成员的实例。

13.Unit、Null、Nothing类型
13.1 Null类
Null类只有一个实例对象null,类似于java中的null引用,null可以赋值给任意引用类型AnyRef,但是不能赋值给值类型AnyVal
13.2 Unit类
Unit类型用来标识过程,也就是没用明确返回值的函数,类似于java里的void。Unit类只有一个实例(),没有实质意义。
def sayOk(): Unit = {
println(“ok”)
}
13.3 Nothing类
Nothing类可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回。该类是其他任意类型的子类,可以跟要求返回值的方法兼容。
def test() : Nothing = {
throw new Exception()
}
编程语言之scala基础_第1张图片
编程语言之scala基础_第2张图片
编程语言之scala基础_第3张图片
编程语言之scala基础_第4张图片
编程语言之scala基础_第5张图片

14.递归

package scalaDemo

object Fibnacci {
  def main(args: Array[String]): Unit = {
    println(fibn(7))
  }

  /**
   * @Author: qwerdf@QAQ
   * @Description: 斐波那契数列数列从第3项开始,每一项都等于前两项之和
    * 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597 ...
    * 示例: n=7 输出13
    * 第1次入栈:main栈  println(fibn(7))    最后输出:13
    * 第2次    fibn1栈  fibn(7)    fibn(n - 2) + fibn(n - 1)  返回9:5 + 8 = 13
    * 第3次    fibn(n - 2)  = fibn(5)    返回值8: 5
    *          fibn(n - 1) = fibn(6)    返回值7: 8
    * 第4次    fibn(5 - 2) + fibn(5 - 1) = fibn(3) + fibn(4)  返回值6:2+3=5
    *          fibn(6 - 2) + fibn(6 - 1) = fibn(4) + fibn(5) 返回值5:3+5=8
    * 第5次    f(1) + f(2) = 2
    *          f(2) + f(3) = 1 + f(3)   返回值4:1+2=3
    *          f(2) + f(3) = 1 + f(3)   返回值3:1+2=3
    *          f(3) + f(4)    返回值1:2+3=5
    *第6次     f(1) + f(2) = 2
    *          f(1) + f(2) = 2
    *          f(1) + f(2) = 2
    *          f(2) + f(3) = 1 + f(3)   返回值1:1+2=3
    *第7次     f(1) + f(2) = 2
    *
    *备注:先入栈则后出栈
    *
   * @Date: 2022/4/23
   * @Param null:
   * @return: null
   **/
 //递归函数编译阶段无法推断具体的结果类型,必须指定返回值类型
  val fibn: Int => Int = n => {
      if (n == 1 || n == 2) {
        1
      } else {
        fibn(n - 2) + fibn(n - 1)
      }
  }
}

15.异常处理

package scalaDemo
import com.sun.xml.internal.bind.v2.TODO

object TryCatch {
  def main(args: Array[String]): Unit = {

    /**
      * @Author: qwerdf@QAQ
      * @Description: 将可能发生异常的代码封装在try块中,catch块用来捕获异常并处理,避免程序异常中止
      *              1.在scala中只有一个catch,在java中可以有多个
      *              2.在catch中有多个case,每个case匹配一种异常,即模式匹配思想。
      * @Date: 2022/4/24
      * @Param args:
      * @return: void
      **/
    try {
      val num = 9 / 0
    } catch {
      case ex: ArithmeticException => {
        //TODO  捕获异常,处理业务逻辑
        println("捕获了除数为零的算术异常")
      }
      case ex: Exception => {
        //TODO  捕获异常,处理业务逻辑
        println("捕获了异常")
      }
    } finally {
      //TODO 有无异常都会执行的代码块,一般用于关闭数据库连接、IO流等
      println("执行finally代码块...")
    }

    println("程序继续执行...")
  }
}

你可能感兴趣的:(scala,scala)