scala_day02
01.学习目标
- 掌握scala类与object的用法
- 掌握继承的用法
- 字符串转Int
scala> "2".toInt
res0: Int = 2
- Map的循环
scala> for(k <- map.keys) println(k + "->" +map(k) )
name->banzhang
xingge->mengmengda
scala> for((x,y) <- map) println(x,y)
(name,banzhang)
(xingge,mengmengda)
scala> for(x <- map) println(x._1,x._2)
(name,banzhang)
(xingge,mengmengda)
scala> map.foreach(println)
(name,banzhang)
(xingge,mengmengda)
scala> map.foreach{
| case (x,y) => println(x,y)}
(name,banzhang)
(xingge,mengmengda)
33.函数式编程-groupBy
- List((“男” -> 2), (“女” -> 1), (“女” -> 2)) .groupBy(_._1)
34.函数式编程-reduce、fold
- 聚合操作,可以将一个列表中的数据合并为一个。
- 使用reduce计算List所有元素的和
- List(1,2,3,4,5,6,7,8,9,10) .reduce((x,y) => x + y)
- fold与reduce很像,但是多了一个指定初始值参数
- fold和foldLet效果一致,表示从左往右计算
- List(1,2,3,4,5,6,7,8,9,10) .fold(0)(_ + _) ----柯里化
- foldRight表示从右往左计算
- fold和foldLet效果一致,表示从左往右计算
02.类和对象-创建类和对象
-
多范式的编程语言
-
使用
class
来定义一个类 -
使用
new
来创建对象 -
scala中的main方法只能写在object中
object _01ClassDemo { // 创建类 class Person{ } def main(args: Array[String]): Unit = { // 创建对象 val p = new Person println(p) } }
03.类和对象-定义成员变量
-
创建Person类,添加姓名字段和年龄字段,并对字段进行初始化
-
在main方法中创建Person类对象,设置成员变量为"张三"、20
object _03ClassDemo { class Person { // 定义成员变量 var name = "" var age = 0 } def main(args: Array[String]): Unit = { // 创建Person对象 val person = new Person person.name = "zhangsan" person.age = 20 // 获取变量值 println(person.name) println(person.age) } }
04.类和对象-使用下划线初始化成员变量
-
用_对var修饰的变量初始化
object _04ClassDemo { class Person{ // 使用下划线进行初始化 var name:String = _ var age:Int = _ } def main(args: Array[String]): Unit = { val person = new Person println(person.name) println(person.age) } } 如果要用_去初始化成员变量,必须用var修饰,如果用val修饰,必须手动指定当前值。
05.类和对象-定义成员方法
-
创建一个Customer类,添加成员变量、成员方法
object _05ClassDemo { class Customer { var name:String = _ var sex:String = _ // 定义成员方法 def sayHi(msg:String) = { println(msg) } } def main(args: Array[String]): Unit = { val customer = new Customer customer.name = "张三" customer.sex = "男" customer.sayHi("你好") } }
06.类和对象-访问修饰符
-
Java中的访问控制,同样适用于scala,可以在成员前面添加private/protected关键字来控制成员的可见性。但在scala中,
没有public关键字
,任何没有被标为private或protected的成员都是公共的 -
在main方法中创建该类的对象,测试是否能够访问到私有成员
object _02AccessDemo { class Person { // 定义私有成员变量 private var name:String = _ private var age:Int = _ def getName() = name def setName(name:String) = this.name = name def getAge() = age def setAge(age:Int) = this.age = age // 定义私有成员方法 private def getNameAndAge = { name -> age } } def main(args: Array[String]): Unit = { val person = new Person person.setName("张三") person.setAge(10) println(person.getName()) println(person.getAge()) } }
07.类和对象-主构造器
object _06ConstructorDemo {
// 定义类的主构造器
// 指定默认值
class Person(var name:String = "", var age:Int = 0) {
var address:String= _
println("调用主构造器")
}
def main(args: Array[String]): Unit = {
// 给构造器传入参数
val zhangsan = new Person("张三", 20)
println(zhangsan.name)
println(zhangsan.age)
println("---")
// 不传入任何参数
val empty = new Person
println(empty.name)
println(empty.age)
println("---")
// 指定字段进行初始化
val man40 = new Person(age = 40)
println(man40.name)
println(man40.age)
}
}
08.类和对象-辅助构造器
-
在scala中,除了定义主构造器外,还可以根据需要来定义辅助构造器。scala允许通过多种方式,来创建对象
-
我们把除了主构造器之外的构造器称为辅助构造器。
object _07ConstructorDemo { class Customer(var name:String = "", var address:String = "") { // 定义辅助构造器 def this(arr:Array[String]) = { // 辅助构造器必须要调用主构造器或者其他辅助构造器 this(arr(0), arr(1)) } } def main(args: Array[String]): Unit = { val zhangsan = new Customer(Array("张三", "北京")) println(zhangsan.name) println(zhangsan.address) } }
var age:Int = _; def this(name:String,address:String,age:Int)={ this(name,address) println("调用了自定义的辅助构造器~~~") this.age = age } def this(age:Int)={ this("ww","33") println("调用了自定义的辅助构造器~~~") this.age = age }
09.单例对象
-
object
-
scala中没有Java中的静态成员,我们想要定义类似于Java的static变量、static方法,就要使用到scala中的单例对象——object.
object _08ObjectDemo { // 定义一个单例对象 object Dog { // 定义腿的数量 val LEG_NUM = 4 } def main(args: Array[String]): Unit = { println(Dog.LEG_NUM) } } 1.main方法写在object中 2.object的属性和方法,能直接调用。
10.单例对象-工具类案例
-
编写一个DateUtil工具类专门用来格式化日期时间,定义一个方法,用于将日期(Date)转换为年月日字符串,例如:2030-10-05
object _10ObjectDemo { object DateUtils { // 在object中定义的成员变量,相当于Java中定义一个静态变量 // 定义一个SimpleDateFormat日期时间格式化对象 val simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm") // 相当于Java中定义一个静态方法 def format(date: Date) = simpleDateFormat.format(date) } // main是一个静态方法,所以必须要写在object中 def main(args: Array[String]): Unit = { println(DateUtils.format(new Date())) } } 天然支持用作工具类使用。
11.单例对象-main方法
-
scala和Java一样,如果要运行一个程序,必须有一个main方法。而在Java中main方法是静态的,而在scala中没有静态方法。在scala中,这个main方法必须放在一个单例对象中。
-
方式一
object Main5 { def main(args:Array[String]) = { println("hello, scala") } }
-
方式二
object Main5 extends App { println("hello, scala") }
12.伴生对象
-
在同一个scala文件中,一个class和object具有同样的名字。这个object称为伴生对象,这个class称为伴生类
object _11ObjectDemo { class CustomerService { def save() = { println(s"${CustomerService.SERVICE_NAME}:保存客户") } } // CustomerService的伴生对象 object CustomerService { private val SERVICE_NAME = "CustomerService" } def main(args: Array[String]): Unit = { val customerService = new CustomerService() customerService.save() } } object和class必须同名。 object和class必须在同一个文件里。 能相互访问私有属性。
13.伴生对象-apply方法
-
// 创建一个Array对象
val a = Array(1,2,3,4)object _12ApplyDemo { class Person(var name:String = "", var age:Int = 0) object Person { // 定义apply方法,接收两个参数 def apply(name:String, age:Int) = new Person(name, age) } def main(args: Array[String]): Unit = { // 使用伴生对象名称来创建对象 val zhangsan = Person("张三", 20) println(zhangsan.name) println(zhangsan.age) } }
/** Creates an array of
Int
objects /
// Subject to a compiler optimization in Cleanup, see above.
def apply(x: Int, xs: Int): Array[Int] = {
val array = new Array[Int](xs.length + 1)
array(0) = x
var i = 1
for (x <- xs.iterator) { array(i) = x; i += 1 }
array
}
14.继承
-
面向对象,通过继承来减少重复代码。
-
使用extends关键字来实现继承
-
语法
class/object 子类 extends 父类 { .. }
-
继承代码
class Person { var name = "super" def getName = this.name } class Student extends Person object Main13 { def main(args: Array[String]): Unit = { val p1 = new Person() val p2 = new Student() p2.name = "张三" println(p2.getName) } }
-
object继承
class Person { var name = "super" def getName = this.name } object Student extends Person object Main13 { def main(args: Array[String]): Unit = { println(Student.getName) }
15.override和super
-
关于继承,我们在子类中使用override需要来重写父类的成员,可以使用super来引用父类
class Person { val name = "super" def getName = name } class Student extends Person { // 重写val字段 override val name: String = "child" // 重写getName方法 override def getName: String = "hello, " + super.getName } object Main13 { def main(args: Array[String]): Unit = { println(new Student().getName) } }
16.isInstanceOf和asInstanceOf
class Person3
class Student3 extends Person3
object Main3 {
def main(args: Array[String]): Unit = {
val s1:Person3 = new Student3
// 判断s1是否为Student3类型
if(s1.isInstanceOf[Student3]) {
// 将s1转换为Student3类型
val s2 = s1.asInstanceOf[Student3]
println(s2)
}
}
}
1,1.1
scala> 1.isInstanceOf[Int]
res13: Boolean = true
scala> 1.isInstanceOf[Double]
res15: Boolean = false
scala> 1.2.isInstanceOf[Double]
res16: Boolean = true
def panduan(t:T){
t.isinstanceof[List]
println(“这是一个list集合”)
foreach
t.isinstanceof[Map]
println(“这是一个map集合”)
foreach
}
object Myo {
def pd[T](t:T): Unit ={
val b: Boolean = t.isInstanceOf[Map[String,String]]
if(b){
println("这是一个map集合")
//强转成map类型
val map: Map[String, String] = t.asInstanceOf[Map[String,String]]
//循环打印
for ((x,y) <- map) println(x+"-->"+y)
}else if(t.isInstanceOf[List[Int]]){
println("这是一个list集合")
//强转成list类型
val list: List[Int] = t.asInstanceOf[List[Int]]
//循环打印
list.foreach(println)
}
}
def main(args: Array[String]): Unit = {
val map: Map[String, String] = Map("name"->"dbf4","sex"->"nan")
val list: List[Int] = List(1,2,3,4)
Myo.pd(list)
}
}
17.getClass和classOf
-
isInstanceOf 只能判断对象是否为指定类以及其子类的对象,而不能精确的判断出,对象就是指定类的对象。如果要求精确地判断出对象就是指定类的对象,那么就只能使用 getClass 和 classOf 。
class Person4 class Student4 extends Person4 object Student4{ def main(args: Array[String]) { val p:Person4=new Student4 //判断p是否为Person4类的实例 println(p.isInstanceOf[Person4])//true //判断p的类型是否为Person4类 println(p.getClass == classOf[Person4])//false //判断p的类型是否为Student4类 println(p.getClass == classOf[Student4])//true } }
18.抽象类_抽象方法
-
定义抽象类和Java一样,在类前面加上abstract关键字
// 定义抽象类 abstract class 抽象类名 { // 定义抽象字段 val 抽象字段名:类型 // 定义抽象方法 def 方法名(参数:参数类型,参数:参数类型...):返回类型 }
-
抽象方法
// 创建形状抽象类 abstract class Shape { def area:Double } // 创建正方形类 class Square(var edge:Double /*边长*/) extends Shape { // 实现父类计算面积的方法 override def area: Double = edge * edge } // 创建长方形类 class Rectangle(var length:Double /*长*/, var width:Double /*宽*/) extends Shape { override def area: Double = length * width } // 创建圆形类 class Cirle(var radius:Double /*半径*/) extends Shape { override def area: Double = Math.PI * radius * radius } object Main6 { def main(args: Array[String]): Unit = { val s1:Shape = new Square(2) val s2:Shape = new Rectangle(2,3) val s3:Shape = new Cirle(2) println(s1.area) println(s2.area) println(s3.area) } }
19.匿名内部类
abstract class Person7 {
def sayHello:Unit
}
object Main7 {
def main(args: Array[String]): Unit = {
// 直接用new来创建一个匿名内部类对象
val p1 = new Person7 {
override def sayHello: Unit = println("我是一个匿名内部类")
}
p1.sayHello
}
}
abstract class person{
def say={
println("你很帅~~")
}
}
def main(args: Array[String]): Unit = {
val person = new person {
override def say: Unit = println("一般般~~~")
}
person.say
}
}