映射
映射就是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 {
}