面向对象
1.对象:用object修饰的语法结构
2.类:用class修饰的
3.类的实例:new 类() 类的实例
4.面向对象的三大特征
(1)封装
(2)继承
(3)多态
5.抽象类
6.Trait(接口)
对象
Object
1.单例的,静态的,scala中根本没有static关键字,为了弥补scala中没有static关键字,scala中使用object代替
2.Static:object代替了static的功能
3.Object本身,没有构造方法,但是他可以定义成员变量和成员属性,不能new
伴生对象
是一类特殊的对象,类和对象相伴而生,对象称之为类的伴生对象,类称之为对象的伴生类
伴生的条件
1.object的名称必须和类的名称一样
2.必须在同一个源文件中,在同一个scala文件中
特点:可以相互访问对象的私有成员属性和方法
class HelloScala {
private val name = "taotao"
}
object HelloScala {
def main(args: Array[String]): Unit = {
val h1: HelloScala = new HelloScala()
val name: String = h1.name
println(name)
}
}
//输出
taotao
对象上有一个特殊的方法:Apply
Apply有一个功能:创建实例
对象()—>默认调用的是该对象中的apply方法
def apply(): ApplyDemo = new ApplyDemo()
//定义一个apply的重载方法
def apply(x: Int, y: Int): Int = {
x * 10 + y * 10
}
def main(args: Array[String]): Unit = {
//相当于调用了ApplyDemo.apply()方法
println(ApplyDemo())
//相当于调用了ApplyDemo.apply(10,20)方法
val result: Int = ApplyDemo(10, 20)
println("result:" + result)
val result2: Int = ApplyDemo.apply(10, 20)
println("result2:" + result2)
val result3: Int = apply(10, 20)
println("result3:" + result3)
}
//输出
org.taotao.fuxi.ApplyDemo@5ba23b66
result:300
result2:300
result3:300
App
App特质,里面定义了Main方法,对象extends App后,可以不用写main
object AppDemo extends App {
//继承了APP以后,就相当有了main方法,可以直接执行
println("12345")
}
//输出
12345
类
成员属性,成员方法(object中也有成员方法)
class Person {
//定义一个变量
//val隐藏了get方法,var隐藏了get和set方法
val name: String = "taotao"
//_是占位符,待指的意思,可以变化
var age: Int = _
def speak() = {
println("你听过一首哲理的歌么?")
}
//alt+fn+insert
//重写toString
override def toString = s"Person($name, $age)"
}
object Person {
def sing() = {
println("这里的山路十八弯")
}
def main(args: Array[String]): Unit = {
val p: Person = new Person()
val name: String = p.name
p.age = 20
val age: Int = p.age
println(name + " " + age)
//插值法输出,字符串前面加s,用$去引用就ok
println(s"name=${p.name},age=${p.age}")
p.speak() //可以调用伴生类中的成员方法
Person.sing()
}
}
//输出
taotao 20
name=taotao,age=20
你听过一首哲理的歌么?
这里的山路十八弯
注意:
1.val修饰的变量,只能有get方法
2.Var修饰的变量,可以有get和set方法
3.如果重写toString,则ALT+Fn+INSERT
构造器
1.scala中的构造器,类似java中的构造器
2.Scala中的构造器分为两类:主构造器和辅助构造器
3.主构造器只有一个,辅助构造器可以有多个
class Student(val name: String, val age: Int) {
//无参辅助构造器
def this() = {
//辅助构造器的第一行,必须调用主构造器,或者其他的辅助构造器
this("taotao", 20)
}
var scc: String = _
//有参的辅助构造器,赋值语句需要写在第一行
def this(name: String, age: Int, scc: String) = {
this(name, age)
this.scc = scc
}
override def toString = s"Student($scc, $name, $age)"
}
object Student {
def main(args: Array[String]): Unit = {
//调用类的无参构造器,默认使用主构造器
val student1: Student = new Student()
println("主构造器:"+student1)
val student: Student = new Student("huahua", 19)
println("辅助构造器:"+student)
println(s"${student.name},${student.age}")
val stu: Student = new Student("taotao", 20, "xixi")
println(stu)
}
}
//输出
主构造器:Student(null, taotao, 20)
辅助构造器:Student(null, huahua, 19)
huahua,19
Student(xixi, taotao, 20)
注意:
1.主构造器的作用域,是在他整个类的大括号范围之内,除了定义的方法,全是他的作用域
2.主构造器只能有一个,和类的定义交织在一起
3.辅助构造器的使用,def this(参数列表),来定义
4.主构造器中的变量,使用val和var来声明,就是成员属性,在外部也可以访问,如果不加修饰符,只能在类的内部使用参数名称而已
5.辅助构造器的第一行,必须调用主构造器或者其他的辅助构造器
6.主构造器的参数必须要赋值
7.辅助构造器的参数不能和主构造器的参数和结构一致
优先使用主构造器
访问权限
指的是成员方法和成员属性能不能在其他访问的到
成员属性:
默认的访问权限:共有的
方法:普通方法和构造器
class Girls private(val age: Int) {
//私有的
//如果类中有私有属性,不想在其的伴生对象中访问到,那么
//private[this] 如果是这种格式,只有本类中才能访问
//还可以在private[包的名字]让属性在哪些包以及子包中可以访问的到
private val name = "taotao"
def this() {
this(11)
}
}
object Girls {
//伴生对象可以访问伴生类私有的属性和方法,其他类中不可以
def main(args: Array[String]): Unit = {
val girls: Girls = new Girls(11)
val name: String = girls.name
println(name + " " + girls.age)
}
}
//输出
taotao 11
注意:
1.一般情况下,我们根本不会刻意去加private权限,以后只要知道在哪家就可以了
2.默认的访问权限是公有的
3.Private 在当前类,伴生对象中可以访问,在其他的地方无法访问
4.Private[this] 只有在当前类中有效,其他地方都无效
5.Private[包名]在指定包的下面都有效
抽象类
Abstract修饰
特点:可以有抽象方法,实例方法,不能new,抽象类有构造器
特质 Trait
Trait:类似于java中的接口,功能更加强大,混入特质:extends和with
特质里是没有构造器的
Java中的接口:interface —》implements
多实现
Java中的接口,可以写实现类
特点,没有构造器,有抽象方法,非抽象方法
1.子类继承父类,调用extends,如果混入特质,用extends,with
2.当没有显示父类时候,第一个必须调用extends,其他特质都用with
模式匹配
1.match+一系列的case(条件)=>
2.模式匹配是有返回值的
(1)匹配内容
(2)匹配类型
(3)匹配数组
(4)匹配元组
(5)匹配list集合
(6)匹配样例类和样例对象
(7)匹配option(some,none)
匹配内容:
val arr: Array[String] = Array("taotao", "huahua", "jianjian")
//随机获取索引
val num: Int = Random.nextInt(arr.length)
println(num)
arr(num) match {
case "taotao" => println("哈哈哈")
case "huahua" => println("嘻嘻嘻")
case "jianjian" => println("嘿嘿嘿")
//解决匹配不上的问题
case _ => println("nomatch")
}
//输出
0
哈哈哈
匹配类型:
val array: Array[Any] = Array[Any](10, 6.6, "taotao")
val num: Int = Random.nextInt(array.length)
println("抽到第:" + num + 1)
array(num) match {
//加守卫
case x: Int if x > 10 => println(x)
case y: Double => println(y)
case z: String => println(z)
//匹配不到的,带守卫的匹配不上,到这里
case _ => println("no match")
}
//输出
抽到第:11
6.6
匹配数组:
整体的匹配:
val arr: Array[Int] = Array[Int](1, 3, 4, 5, 6)
arr match {
case Array(a, b, x, y, z) => println(s"a=${a},b=${b},x=${x},y=${y},z=${z}")
case Array(1, _*) => println("match")
}
//输出
a=1,b=3,x=4,y=5,z=6
匹配元组:
要求最大值和最小值一起返回
//接收方式
val (max, min) = getValues(Array(1, 3, 5, 7, 8, 3, 9, 0))
val tp2 = getValues(Array(1, 3, 5, 7, 8, 3, 9, 0))
val tp1 = (tp2._1, tp2._2, true)
println("tp1:"+tp1)
val tp = (max, min, true)
tp match {
case (x, y, z) => println(s"x=${x},y=${y},z=${z}")
case (x, _, _) => println(x)
case _ => println("no match")
}
//输出
tp1:(9,0,true)
x=9,y=0,z=true
匹配list集合
val list1: List[Int] = List[Int](1, 3, 4)
list1 match {
case List(x, y, z) => println(s"x=${x},y=${y},z=${z}")
// x为头元素,y为尾元素
case x :: y => println(s"x=${x},y=${y}")
// x::y::Nil这样是不可以的,因为有Nil的时候为具体元素,少一个z是不可以的
case x :: y :: z :: Nil => println(s"x=${x},y=${y},z=${z}")
case _ => println("no match")
}
//输出
x=1,y=3,z=4
匹配样例类和样例对象
1、样例类:
(1)特殊的类:case class person
(2)样例对象:case object person
(3)样例类的特点:
①样例类,不能new
②Case class 必须有主构造器
③默认实现了,equals,hashcode,toString
④实现序列化特质
scala> case class person(name:String,age:Int)
defined class person
scala> val p1=person("li",27)
p1: person = person(li,27)
scala> val p2=person("li",27)
p2: person = person(li,27)
scala> p1==p2
res0: Boolean = true
样例类支持模式匹配样例
匹配option
val map: Map[String, Int] = Map[String, Int]("a" -> 100, "b" -> 200, "c" -> 300)
//取值get
val maybeInt: Option[Int] = map.get("a")
val result: Int = maybeInt match {
case Some(v) => v
case None => -1
}
println(result)
//输出
100
偏函数
Def 方法名称 partialFunction[输入参数,返回值类型]={
Case xx=>xx
}
省略match
def meth1(name: String): Int = name match {
case "taotao" => 100
case "huahua" => 90
case _ => -1
}
def pf: PartialFunction[String, Int] = {
case "taotao" => 100
case "huahua" => 90
case _ => -1
}
def pf2: PartialFunction[Any, Int] = {
case x: Int => x * 10
case _ => -1
}
def main(args: Array[String]): Unit = {
println(meth1("taotao"))
println(pf("taotao"))
val arr: Array[Any] = Array[Any](1, 2, 4, 5, "error")
val num: Array[Int] = arr.map(pf2)
println(num.toList)
//还有一些具体的方法必须偏函数
val num1: Array[Int] = arr.collect(pf2)
println(num1.toList)
}
//输出
100
100
List(10, 20, 40, 50, -1)
List(10, 20, 40, 50, -1)