scala 构造,继承,抽象,静态,伴生,caseclass,数组,列表,映射,元祖,集合

scala之构造函数

ctrl+alt+b:查找接口的实现类

首先写在main函数里的:

 //3个入参
 // new的时候其实就是调用的构造方法
val person2 = new Person("J总",18,gender = "asd")
//输出4个
println(person2.name + "," + person2.age + "," + person2.school + "," + person2.gender)

调用的构造函数如下

class Person(val name:String, val age:Int){
  println("---ru---")

  var school = "ustc"

  var gender:String = "nv"

  println("--leave--")
  
//既然是3个入参,那么优先使用这里的方法和属性
/**
    * 附属构造器def this
    *   第一行必须要调用已有的主构造器,或者附属构造器
    */
  def this(name:String,age:Int,gender:String){

    this(name,age)
    println("asd")
    this.gender=gender
    this.school="stu"
  }

  def this(name: String,age:Int,gender:String,school:String){
//这里3个参数,调用的是上一个辅助
    this(name,age,gender)
    this school=school
    println("ktv")
  }
}

输出结果:

---ru---
--leave--
asd
J总,18,stu,asd

看看debug过程:
scala 构造,继承,抽象,静态,伴生,caseclass,数组,列表,映射,元祖,集合scala 构造,继承,抽象,静态,伴生,caseclass,数组,列表,映射,元祖,集合

scala的继承

写在main里的

val student = new Student(name = "xiaodoudou",age = 12,major = "student")
println(student.name + "," + student.age +"," +student.major + "," +student.kkk())

注意,由于父类没有major的类型,要定义常量变量符,重写方法和变量要用override,tostring这个看似在父类没定义,但是其实是隐藏的

class Student(name:String,age:Int, val major:String) extends Person(name,age){
  println("---Student Leave---")

   override def toString() ="student tostring"

   def kkk()="fuck"

   val english = "bad"

  println("--student leave--")
}

所有代码

package com.ruozedata.bigdata.scala02

object ConstrutorApp {
  def main(args: Array[String]): Unit = {
//    val person = new Person("asd",30)
//
//    println(person.name + " , " + person.age + " , " + person.school)

    val person2 = new Person("J总",18,gender = "asd")
    println(person2.name + "," + person2.age + "," + person2.school + "," + person2.gender)

//      val student = new Student(name = "xiaodoudou",age = 12,major = "student")
//      println(student.name + ","  + student.age + "," +student.major + "," +student.kkk())
    }


}

class Person(val name:String,  var age:Int){
  println("---ru---")

  var school = "ustc"
  val xxx ="xxx"
  var gender:String = "nv"

  println("--leave--")

  def this(name:String,age:Int,gender:String){

    this(name,age)
    println("asd")
    this.gender=gender
    this.school="stu"
  }

  def this(name: String,age:Int,gender:String,school:String){

    this(name,age,gender)
    this school=school
    println("ktv")
  }
}

class Student(name:String, age:Int  ,val major:String) extends Person(name,age){
  println("---Student Leave---")

   override def toString() ="student tostring"

  override val xxx: String = "kkk"
   def kkk()="fuck"

   val english = "bad"

  println("--student leave--")
}

抽象类

用abstract修饰的class

/**
  * 抽象类: abstract class
  * 1)一个或者多个方法只有定义没有实现
  * 2) 不能直接使用,必须要有具体的实现类
  */
object AbstractApp {
  def main(args: Array[String]): Unit = {
    //抽象类不能new,但是,可以自己实现自己的抽象后new
    val s = new Person2 {
      override def hit: Unit = "asd"

      override val name: String = "asd"
    }
    println(s.name)

  }
}

abstract class Person2{
  def hit
  val name:String
}

//抽象都要实现,如果继承的类不是抽象的,这里的参数也不能使用占位符 _ 代替。
class Student2 extends Person2{
  override def hit: Unit = {
    println("asd hit asd")
  }

  override val name: String = "xxx"
}

所有代码

package com.ruozedata.bigdata.scala02

object AbstractApp {
  def main(args: Array[String]): Unit = {
    //抽象类不能new
    val s = new Person2 {
      override def hit: Unit = "asd"

      override val name: String = "asd"
    }
    println(s.name)

  }
}

abstract class Person2{
  def hit
  val name:String
}

//抽象都要实现
class Student2 extends Person2{
  override def hit: Unit = {
    println("asd hit asd")
  }

  override val name: String = "xxx"
}

object与静态

//object是静态的,几个object对象共享一个变量
object Timer2 {
  var timer = Timer
  var timer2 = Timer

  def main(args: Array[String]): Unit = {
    for (i <- 1 to 3) {
      println(timer.incr())

    }
    println(timer2.index)
  }
}


object Timer {
  var index =0

  def incr() ={
    index = index +1
    index
  }
}

结果:

1
2
3
3

所有代码

package com.ruozedata.bigdata.scala02

object Timer {
  var index =0

  def incr() ={
    index = index +1
    index
  }

  //从结果可知,object就像是静态,动态在子程序中,每次调用都会从它的初始值开始调用
  //静态变量会从变化后的值继续改变
  def main(args: Array[String]): Unit = {
    for (i <- 1 to 10){
      println(incr())
    }


  }
}

伴生类和伴生对象

调用object里的方法

object Applyapp {
  def main(args: Array[String]): Unit = {
    println(ApplyTest.inc)
  }
}

object ApplyTest{
  println("comrin")

  var count=0
  //注意这里,没()也不报错
  def inc={
    count=count+1
    count
  }

  def static()={
    println("object ApplyTest static")
  }
  println("out")
}

执行顺序是,先进入ApplyTest,把他的参数和print都执行,然后调用inc函数。

结果:

comrin
out
1

空class的返回值:

def main(args: Array[String]): Unit = {
         val a =new ApplyTest
	 println(a)
  }
  
class ApplyTest{

}

返回的是tostring的值:

[email protected]

apply函数

apply函数在class和object里默认使用,通常做法是object的apply里new一个类。

main函数里

   val b = ApplyTest()
    println(b)
    b.test()

//伴生对象和类,object可以直接调用,class要new
class ApplyTest{

  def test()={
    println("class Applytest enter")
  }
}


object ApplyTest{
  println("comrin")

  var count=0
  def inc={
    count=count+1
    count
  }

//建了个对像
  def apply()={
    println("object apply")
    new ApplyTest
    
  }

  def static()={
    println("object ApplyTest static")
  }
  println("out")
}

结果进入了apply方法,里面new了一个class,和上一个实验结果一样,返回了tostring和class里的方法

comrin
out
object apply
[email protected]
class Applytest enter

其实class里也会进入apply方法

main里:
val c = new ApplyTest
    println(c)
    c()

class ApplyTest{

  def test()={
    println("class Applytest enter")
  }

  def apply()={
    println("class apply")

  }
}

返回

[email protected]
class apply

所有代码

package com.ruozedata.bigdata.scala02

object Applyapp {
  def main(args: Array[String]): Unit = {
  //  println(ApplyTest.inc)
//    val a =new ApplyTest
//    //返回的是tostring的返回值
//    println(a)
//      val b = ApplyTest()
//    println(b)
//    b.test()

    val c = new ApplyTest
    println(c)
    c()
  }


}

//伴生对象和类,object可以直接调用,class要new
class ApplyTest{

  def test()={
    println("class Applytest enter")
  }

  def apply()={
    println("class apply")

  }
}

object ApplyTest{
  println("comrin")

  var count=0
  def inc={
    count=count+1
    count
  }

  def apply()={
    println("object apply")
    new ApplyTest
  }

  def static()={
    println("object ApplyTest static")
  }
  println("out")
}

并非所有class只有new才能用,caseclass

object CaseClassApp {
  def main(args: Array[String]): Unit = {
    println(Dog)
    println(Dog("wanwan"))
    println(Dog("wanwan").name)
  }
}

case class Dog(name:String)

结果:

Dog
Dog(wanwan)
wanwan

所有代码

package com.ruozedata.bigdata.scala02

object CaseClassApp {
  def main(args: Array[String]): Unit = {
    println(Dog)
    println(Dog("wanwan"))
    println(Dog("wanwan").name)
  }
}

case class Dog(name:String)

数组集合

object ArrayApp {
  def main(args: Array[String]): Unit = {
//定常数组
    val a = new Array[String](5)
    println(a)

    a.length
    //赋值,1是索引,从0开始
    a(1)="ruoze"

    val b =Array("ruoze","jge")
    b(1)="xxx"

    //,拼接
    a.mkString(",")
    a.mkString("[","&","]")

    //变长数组
    //要导入包
    import scala.collection.mutable.ArrayBuffer
    val c = ArrayBuffer[Int]()

      //添加1,2
      c += 1
      c += 2

      c += (3,4,5)
      c ++= Array(6,7,8)
      //第0个位置加0
      c.insert(0,1)
      //把索引为1的移走
      c.remove(1)
        //从第几个位置移几个
      c.remove(1,3)
      //移掉最后两个
      c.trimEnd(2)
        //把可变数组变为不可变
      c.toArray

      val c =ArrayBuffer[Int](1,2,3,4)
      c += 1
      c.toArray
//两种遍历写法
      for(i<-0 until c.length){
          println(c(i))
      }

      for (ele<-c) {
          println(ele)
      }

  }
}

列表

object ListApp {
  //Nil可以生成个不可变的列表
  var a = Nil
  //正常集合构建方法
  val l =List(1,2,3,4,5)

  //list 只有头和尾,尾是除了第一个元素外的其他元素
  l.head
  l.tail

  //1拼接一个空的列表就是只有1的列表
  val l2 = 1::Nil
  val l3= 2::l2

  //可变列表
  import scala.collection.mutable.ListBuffer
  val l4 =ListBuffer[Int]()

  l4 ++= List(1,2,3)
//虽然没有4,但是也不会报错
  l4 -= (1,4)
  l4 --= l4(2,3)

  l4.toArray
  l4.toList

  l4.isEmpty

  def sum(nums:Int*):Int= {
    if (nums.length == 0) {
      0
    } else {
        //自己调用自己,变类型
      nums.head + sum(nums.tail: _*)
    }

  }

  
}

map键值对

//key-value
object MapApp {
  def main(args: Array[String]): Unit = {
    //不可变的
    val  a =Map("name"->"ruoze","age"->30)
    println(a("name"),a("age"))

    import scala.collection.mutable.HashMap
    val b =HashMap("name"->"ruoze","age"->30)
    b("age")=19

//如果得不到,就报后面那个字符串
    b.getOrElse("gender","unknown")

    b += ("asd"->"dsa")
    println(b)

    for ((key,value)<- b){
      println(key + ":" + value)
    }
//存在就得到key对饮的value,得不到就0
    for ((key,_) <- b){
      println(key +":"+b.getOrElse(key,0))
    }
//b.keySet 为 key的集合
    for (ele <- b.keySet){
      println(ele +":"+ b.getOrElse(ele,0))
    }
    println(b.keySet)

    for (ele <- b.values){
      println(ele)
    }

  }

键值对里的get

val m =Map(1->2)
    println(m(1))
    //返回Some(2)
    println(m.get(1))
    //None
    println(m.get(2))
  //返回2
    println(m.get(1).get)
    //如果用get,原先是None,会报错
    println(m.get(2).getOrElse(0))

元组

object TupleApp {
  def main(args: Array[String]): Unit = {
    val a =(1,2,3,4)
    //取第一个值
    println(a._1)
 
  }
}

list,array,set区别:

set无序,不可重复。
list底层是链表,有序,可重复。
array底层是连续的,查找速度快
这里的有序和无序不是指集合中的排序,而是是否按照元素添加的顺序来存储对象。