Scala(三)

本文深入讲解Scala中的映射(Map)集合使用,包括不可变Map和可变Map的区别,以及如何进行值的获取、更新和迭代操作。同时,详细介绍了Scala的面向对象特性,如封装、继承、多态,以及类的定义、构造器、内部类、单例模式和抽象类的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

映射

映射就是Map集合,由一个(key,value)组成。
-> 操作符用来创建
例如:
val scores = Map(“Alice” -> 10,”Bob” -> 3,”Cindy” -> 8)

映射的类型分为:不可变Map和可变Map

在这里插入图片描述
映射的操作
获取映射中的值

在这里插入图片描述
更新映射中的值(必须是可变Map)
在这里插入图片描述
迭代映射
在这里插入图片描述

举例:
		创建一个Map来保存学生的成绩
		
		scala> val scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
		scores: scala.collection.immutable.Map[String,Int] = Map(Tom -> 80, Andy -> 85, Mike -> 82)
		
		说明:
		Map[String,Int]  key是String value是Int
		
		scala中,映射是有两种,一种是可变的,一种是不可变的
		scala.collection.immutable  不可变Map
		scala.collection.mutable   可变
		
		scala> val scores = scala.collection.mutable.Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
		scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80, Andy -> 85)
		
		scala> val scores = scala.collection.mutable.Map(("Tom",80),("Andy",85),("Mike",82))
		scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80, Andy -> 85)
		
	映射的操作:
		
		1、获取映射中的值
			
			scala> scores("Tom")
			res0: Int = 80

			scala> scores.get("Andy")
			res1: Option[Int] = Some(85)

			scala> scores.get("Anddskfjlskjdfly")
			res2: Option[Int] = None

			get方法不会报错,直接取值会报错
			scala> scores("sldfkjlskdjflksd")
			java.util.NoSuchElementException: key not found: sldfkjlskdjflksd
			  at scala.collection.MapLike$class.default(MapLike.scala:228)
			  at scala.collection.AbstractMap.default(Map.scala:59)
			  at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
			  ... 32 elided

			scala> scores.contains("Tom")
			res4: Boolean = true

			scala> scores.contains("Todfkjlskdjflksjdm")
			res5: Boolean = false

			如果取到Tom,则返回。未取到,则返回-1。
			scala> scores.getOrElse("Tom",-1)
			res6: Int = 80

			scala> scores.getOrElse("Tosldkfjlskdjflksdjflm",-1)
			res7: Int = -1
			
	2、更新映射中的值
		
		注意:必须操作是可变映射
		
		scala> scores
		res8: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80, Andy -> 85)

		scala> scores("Andy")
		res9: Int = 85

		scala> scores("Andy") = 90

		scala> scores
		res11: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80, Andy -> 90)
		
	3、映射的迭代
		
		使用foreach
		
		scala> for(s <- scores) println(s)
		(Mike,82)
		(Tom,80)
		(Andy,90)

		scala> scores.foreach(println)
		(Mike,82)
		(Tom,80)
		(Andy,90)

Scala语言的面向对象

面向对象的基本概念

把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象
面向对象的三大特征:

封装
继承
多态

类的定义
简单类和无参方法:

在这里插入图片描述
案例:注意没有class前面没有public关键字修饰
在这里插入图片描述
如果要开发main方法,需要将main方法定义在该类的伴生对象中,即:object对象中
在这里插入图片描述

class Student1 {
  //定义学生属性
  private var stuId : Int = 0
  private var stuName : String = "Tom"
  private var age : Int = 20

  //定义方法(函数)get set
  def getStuName() : String = stuName
  def setStuName(newName : String) = this.stuName = newName

}
/**
 *测试student1类,创建main函数,写到object里面
 *
 * 注意:object和class的名字 可以不一样
 * 如果一样的话,这个object就叫做class的伴生对象
 */

object Student1 {
  def main(args: Array[String]): Unit = {
    //创建一个学生对象
    var s1 = new Student1
    //访问属性并输出
    println(s1.getStuName())

    //访问set方法
    s1.setStuName("Wind")
    println(s1.getStuName())

    println("---------访问私有属性---------")
    println(s1.stuId + "\t" + s1.getStuName() + "\t" + s1.age)

    /**
     * 属性的get set 方法
     *  1、当一个属性是private的时候,Scala会为其自动生成get set 方法
     *  方法名与属性名一致
     *
     *  2、如果只希望Scala生成get方法,不生成set方法,可以将它定义为常量
     *
     * 3、如果希望属性不能在外部访问,使用private[this] 关键字
     */
  }
}

属性的getter和setter方法

当定义属性是private时候,scala会自动为其生成对应的get和set方法
private var stuName:String = "Tom"

get方法: stuName ----> s2.stuName() 由于stuName是方法的名字,所以可以加上一个括号
set方法: stuName_= ----> stuName_= 是方法的名字

定义属性:private var money:Int = 1000 希望money只有get方法,没有set方法??
办法:将其定义为常量private val money:Int = 1000

private[this]的用法:该属性只属于该对象私有,就不会生成对应的set和get方法。如果这样,就不能直接调用,例如:s1.stuName —> 错误

内部类(嵌套类)

我们可以在一个类的内部在定义一个类,如下:我们在Student类中,再定义了一个Course类用于保存学生选修的课程。
在这里插入图片描述
开发一个测试程序进行测试:
在这里插入图片描述

class Student2 {
  private var StuName : String = "Tom"
  private var StuAge : Int = 20

  //定义一个数组保存学生课程成绩
  private var courseList = new ArrayBuffer[Course]()

  //定义一个函数,用于添加学生的课程成绩
    def addNewCourse(cname:String,grade:Int): Unit ={
      //创建课程的成绩信息
      var c = new Course(cname,grade)
      //添加到学生对象中  courseList中
      courseList += c

    }

  //定义课程表:主构造器,即把属性写到类名后面
  class Course (var courseName : String,var grade : Int){

  }
}
object Student2{
  def main(args: Array[String]): Unit = {
    //测试程序 创建学生对象
    var s = new Student2
    s.addNewCourse("Chinese",80)
    s.addNewCourse("Math",70)
    s.addNewCourse("English",60)

    println(s.StuName + "\t" + s.StuAge)
    println("----------课程信息--------")
    for (c <- s.courseList) println(c.courseName + "\t" + c.grade)
  }
}

类的构造器

类的构造器分为:主构造器、辅助构造器
主构造器:和类的声明结合在一起,只能有一个主构造器
Student4(val stuName:String,val stuAge:Int)
(1) 定义类的主构造器:两个参数
(2) 声明了两个属性:stuName和stuAge 和对应的get和set方法

在这里插入图片描述
辅助构造器:可以有多个辅助构造器,通过关键字this来实现

在这里插入图片描述

class Student3 (var stuName:String,var age:Int){
  //属性
  private var gender : Int = 1


  /**
   * 定义辅助构造器,辅助构造器可以有多个
   *
   * 辅助构造器就是一个函数,只不过这个函数的名字叫 this
   */

  def this(age:Int){
    this("Mike",age)//相当于new student3("Mike",age)
    println("这是辅助构造器 this(age:Int)")
  }

  def this(){
    this(10)//相当于new student3("Mike",10)
    println("这是辅助构造器 this()")

  }
}
object Student3{
  def main(args: Array[String]): Unit = {
    //使用主构造器创建学生对象
    var s1 = new Student3("Tom",20)
    println(s1.stuName + "\t" + s1.age)

    //使用辅助构造器创建学生对象
    var s2 = new Student3(20)
    s2.gender = 0
    s2.stuName = "Lily"
    println(s2.stuName + "\t" + s2.age + "\t" + s2.gender)
  }
}

Scala中的Object对象

Scala没有静态的修饰符,但Object对象下的成员都是静态的 ,若有同名的class,这其作为它的伴生类。在Object中一般可以为伴生类做一些初始化等操作。
下面是Java中的静态块的例子。在这个例子中,我们对JDBC进行了初始化。

在这里插入图片描述
而Scala中的Object就相当于Java中静态块。

Object对象的应用
单例对象

在这里插入图片描述
使用应用程序对象:可以省略main方法;需要从父类App继承。
在这里插入图片描述
单例模式


object CreditCard {

    //定义一个变量保存信用卡号  private [this] 代表不会自动生成get set 方法
    private [this] var creditCardNumber : Long = 0

    //定义函数产生卡号
    def generateCCNumber() : Long = {

      creditCardNumber += 1
      creditCardNumber
    }

    def main(args: Array[String]): Unit = {
      println(CreditCard.generateCCNumber())
      println(CreditCard.generateCCNumber())
      println(CreditCard.generateCCNumber())
      println(CreditCard.generateCCNumber())
      println(CreditCard.generateCCNumber())
      println(CreditCard.generateCCNumber())
    }
}

继承App

object HelloWorld extends App{
  println("Hello World")

  if (args.length > 0){
    println("有参数")
  } else {
    println("没有参数")
  }
}

Scala中的apply方法

遇到如下形式的表达式时,apply方法就会被调用:
Object(参数1,参数2,…,参数N)
通常,这样一个apply方法返回的是伴生类的对象;其作用是为了省略new关键字

在这里插入图片描述
在这里插入图片描述

class Student4 (var stuName : String)


/**
 * 定义Apply方法
 * */

object Student4{
  def apply(name : String) = {
    println("调用了apply方法")
    new Student4(name)
  }

  def main(args: Array[String]): Unit = {
    //使用主构造器创建学生对象
    var s1 = new Student4("Tom")
    println(s1.stuName)

    //使用apply方法创建学生对象
    var s2 = apply("Mary")
    println(s2.stuName)
  }
}

Scala中的继承

Scala和Java一样,使用extends关键字扩展类。
案例一:Employee类继承Person类

在这里插入图片描述
案例二:在子类中重写父类的方法
在这里插入图片描述
案例三:使用匿名子类
在这里插入图片描述
案例四:使用抽象类。抽象类中包含抽象方法,抽象类只能用来继承。
在这里插入图片描述
案例五:使用抽象字段。抽象字段就是一个没有初始值的字段
在这里插入图片描述
继承

/**
 * @Autho:Administrator and wind
 * @Version:2019/11/3 & 1.0
 *
 * Person 人 父类
 * Emplyee 员工 子类
 *
 */

//定义父类
class Person(val name:String,val age:Int){
  //定义函数
  def sayHello():String = "Hello " + name + " and the age is " + age
}
//定义子类
class Emplyee(override val name:String,override val age:Int,val salary:Int)extends Person(name,age){
  override def sayHello(): String = "这是子类中的sayHello"
}

object Demo1 {

  def main(args: Array[String]): Unit = {
    //创建父类
    var p1 = new Person("Tom",20)
    println(p1.name +"\t" + p1.age)
    println(p1.sayHello())

    //创建子类
    var p2 = new Emplyee("Mike",22,1000)
    println(p2.name + "\t" + p2.age +"\t" + p2.salary)
    println(p2.sayHello())

    //创建匿名类
    var p3 = new Person("Lily",20)
    println(p3.name + "\t" +p3.age)
    println(p3.sayHello())
  }
}

抽象类

/**
 * @Autho:Administrator and wind
 * @Version:2019/11/3 & 1.0
 *
 * 抽象类
 */

//定义父类:抽象类--交通工具类
abstract class Vehicle{
  //定义抽象方法,但不需要实现
  def checkType():String
}

//定义子类--自行车、汽车  从父类继承
class Car extends Vehicle{
  override def checkType(): String = "I am a Car"
}

class Bike extends Vehicle{
  override def checkType(): String = "I am a Bike"
}

object Demo2 {

  def main(args: Array[String]): Unit = {
    var v1 :Vehicle = new Car
    println(v1.checkType())

    var v2 :Vehicle = new Bike
    println(v2.checkType())
  }
}

抽象字段

abstract class Person1{
  //定义抽象字段
  val name : String
  val age : Int
}
abstract class Emplyee1 extends Person1{

}
class Emplyee2() extends Person1{

  val name : String = "Tom"
  val age : Int = 20
  //class Emplyee2(val name : String,val age :Int) extends Person1  主构造器
}
object Demo3 {

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值