Scala语法(三)

scala构造器

主构造器
1.在scala中,主构造器是和类名放在一起的,有且只有一个,与java不同,java可以有多个构造方法,多个构造方法之间可以实现重载
2.主构造器还可以通过使用默认参数,来给参数默认的值
3.在类中,没有定义在任何方法中的代码(包括成员类型),都属于主构造器的代码,且执行顺序与代码的书写的顺序是一致的
4.如果主构造器的参数使用val或者var修饰了,那么就是成员属性,否则就仅仅是一个局部变量
5.主构造器的参数必须赋值
辅助构造器
1.辅助构造器可以又多个
2.多个辅助器之间可以调用
3.辅助构造器中的参数不可以使用val/var
4.辅助构造器的第一行必须调用主构造器或者其他辅助构造器
私有构造器
1.私有构造器是针对于主构造器
2.如果声明了私有构造器,那么只能被他的伴生对象访问
3.如果主构造器设置为私有构造器,那么辅助构造器依然可以访问

class Teacher private (var name:String, val age:Int = 34) {
  val id:Int = 1
  var sex:String = _
  private var pro:String = _

  println("俺是主构造器")

  //定义一个辅助构造器,def this()
  //辅助构造器的参数不能使用val/var修饰符
  def this(name:String,age:Int,sex:String){
    //第一句话必须是先调用主构造器
    this(name,age)
    println("第一个辅助构造器")
    this.sex=sex

  }


  def this(name:String,age:Int,sex:String,pro:String){
    //调用第一个辅助构造器
    this(name,age,sex)
    println("第二个辅助构造器")
    this.pro = pro
  }
  //打招呼方法
  def sayHello() ={
    //调用Teacher类中的方法
    //伴生对象中可以访问伴生类额私有成员和属性
    Teacher.sayHello(this.name)
  }


}
object Teacher {
  //打招呼方法
  private def sayHello(name:String) ={
    println(s"hello ${name}")
  }

  def main(args: Array[String]): Unit = {
    val teacher = new Teacher("苍老师", 18)
    teacher.sex = "女"
    println(s"启蒙老师:${teacher.name},编号:${teacher.id},性别:${teacher.sex},年龄:${teacher.age}")

    teacher.pro = "XX省"
    val teacher2 = new Teacher("波多老师",28,"男")
    //访问的是Teacher类中的打招呼方法
    teacher2.sayHello()
  }
}

作用域
1.默认是public
2.跟java相似
3. public:表示公共的,任意都可以访问
private:表示私有的, 表示当前类的对象都可以访问(伴生对象和伴生类依然可以访问)
private[this]:当前对象(实例)都可以访问,其他对象不能访问,连伴生对象都不能访问
private[package]:表示某个包下面可以访问,比如private[Spark],表示在Spark包下所有的类都可以访问
伴生对象
1.如果有一个class,还有一个与clas同名的object,那么就称这个object是class的伴生对象,class是object的伴生类
2. 伴生类和伴生对象必须放在一个.scala的文件中
3.伴生类和伴生对象,最大的特点就在于,相互之间可以访问private的字段

class MyGril {
  private var name = "苍老师"
  //输出伴生对象的name
  println(MyGril.name)
}
//一个单例模式
object MyGril{
  private var name = "波多老师"
  //输出伴生类的name
  println(new MyGril().name)

  def apply(name:String) ={
    println(s"女神:${name}")
  }
}

object TestMyGril{
  def main(args: Array[String]): Unit = {
    var gril1 = MyGril("小泽老师")
    var gril2 = MyGril("长泽老师")
  }
}
//结果
//波多老师
//苍老师
//女神:小泽老师
//女神:长泽老师

scala中的object
1.object:相当于java的静态类,类似于java的单例模式,通常在里面放一些class里面共享的内容
2.可以将object看成一个类class,只是这个类在内存中是一个单例,且定义的object就是实例名,不需要我们自己进行实例化,运行与JVM在java中帮我们new出来了
3.第一次调用object方法时,会执行object的构造器,也就是说object内部不再方法中的代码(并且被执行一次),但是object不能定义接收参数的构造器
4.注意object的构造器只是会在第一次调用的时候执行,以后每次调用不会再次执行构造器了
5.使用场景
初始化配置文件
公共处理类(方法)
数据库的初始化

class StaticTest {
  private def add(x:Int,y:Int) ={
    x+y
  }
}
//这个是单例模式的定义,和类名相同,且不带参数
object StaticTest{
  //声明一个实例对象
  private val staticTest = new StaticTest
  println("老子说了算")
  //提供一个公共的方法
  def add(x:Int,y:Int) ={
    staticTest.add(x,y)
  }
}
object StaticTest2{
  def main(args: Array[String]): Unit = {
    println(StaticTest.add(2,3))
    println(StaticTest.add(3,3))
    println(StaticTest.add(4,3))
  }
}
//”老子说了算“只打印一次
//老子说了算
//5
//6
//7

apply方法
当不是new关键字来创建对象的时候,使用apply可以是我们的代码更加简洁

class ApplyTest {
  var name:String = _
  var age:Int = _
}
object ApplyTest{
  //方法中的参数不能使用val/val关键字
  def apply(name:String): ApplyTest = {
   val applyTest = new ApplyTest()
    applyTest.name = name
    applyTest
  }

  def apply(name:String,age:Int) : ApplyTest ={
    val applyTest = new ApplyTest()
    applyTest.name = name
    applyTest.age = age
    applyTest
  }

  def apply(applyTest: ApplyTest)={
    val applyTest = new ApplyTest()
    applyTest
  }
}
object Test{
  def main(args: Array[String]): Unit = {
    //实例化调用
    val applyTest = new ApplyTest()
    applyTest.name = "苍老师"
    applyTest.age = 18
    println(s"name:${applyTest.name},age:${applyTest.age}")

    //apply方法调用一个参数
    val applyTest2 = ApplyTest("小泽老师")
    println(s"name:${applyTest2.name},age:${applyTest2.age}")
    //两个参数
    val applyTest3 = ApplyTest("波多老师",20)
    println(s"name:${applyTest3.name},age:${applyTest3.age}")
    //对象
    val applyTest4 = ApplyTest(applyTest)
    println(s"name:${applyTest4.name},age:${applyTest4.age}")
  }
}

继承
1.在scala中,让子类继承父类,与java一样,使用extends关键字
2.继承就代表,子类可以继承父类的field和method,然后子类可以在自己内部放入父类所没有,子类所特有的field和medthod
3.子类可以重写父类的field和method,但是需要注意的是final关键字,filnal关键字表示field和method不能重写
4.子类中的方法要重写父类的非抽象方法的话,需要override关键字
5.子类的属性val要重写父类的非抽象属性,必须要override
6.子类实现父类的抽象方法或者属性,可以选择性的使用override

abstract class Animal {
  //抽象字段
  var age:Int
  //非抽象
  val weight:Double = 35.0

  //抽象方法
  def color()
  //非抽象
  def eat(): Unit ={
    println("吃肉")
  }
  //final关键字修饰,自身必须有具体的实现
  //被final修饰不能被重写
  final def action() = {
    println("偷桃")
  }
}
class Monkey extends Animal{
  //重写父类抽象字段,可加可不加(override)
  /*override*/ var age: Int = 3

  //非抽象字段,必须加override
  override val weight: Double = 40.0

  //重写抽象方法,可加可不加
  override def color(): Unit = {
    println("棕色")
  }
}
object Monkey{
  def main(args: Array[String]): Unit = {
    val monkey = new Monkey
    monkey.color()

    println(monkey.age)
    println(monkey.weight)
  }
}

特质trait
1.相当于java的接口,实际上比接口功能强大
2.与接口不同的是,特质可以定义属性和方法的实现
3.一般情况下scala的类只能被继承单一的父类,但是如果是特质的话可以实现多继承,从结果上来看实现了多继承
4.特质定义的方式与类类似,但是它使用的关键字是trait

trait TraitDemo01 {
  //val修饰的非抽象字段,可以被重写
  val name:String = "光头强"
  //var修饰非抽象字段,不可以重写
  var age:Int = 18
  //抽象字段
  var sex:String

  //抽象方法
  def say(context:String)
}

trait TraitDemo02{

  def sayHello(context:String)
}
//多重实现
class TraitDemo extends TraitDemo01 with TraitDemo02{
  //抽象 可加可不加
  var sex: String = "男"
  //非抽象字段必须加override
  override val name: String = "熊大"

  override def say(context: String): Unit = {
    println(context)
  }

  override def sayHello(context: String): Unit = {
    println(context)
  }
}
object TraitDemo{
  def main(args: Array[String]): Unit = {
    val traitDemo = new TraitDemo
    traitDemo.say("啊啊啊")
    traitDemo.sayHello("hello!!")
    println(traitDemo.name)
  }
}

比较复杂的trait,加深理解

trait TraitDemo03 {
  println("1:02的主代码块")
}
trait TraitDemo03_01 extends TraitDemo03{
  println("2:03_01的主构造代码块")
}
trait TraitDemo03_02 extends TraitDemo03{
  println("3:03_02的主构造代码块")
}
class Person{
  println("4:Person的主代码块")
}
class Person01 extends Person with TraitDemo03 with TraitDemo03_01 with TraitDemo03_02 {
  println("5:Person01的主代码块")
}

object Student{
  def main(args: Array[String]): Unit = {
    new Person01
  }
}
/*
4:Person的主代码块
1:02的主代码块
2:03_01的主构造代码块
3:03_02的主构造代码块
5:Person01的主代码块
*/

trait小技巧

trait TraitDemo01_03{
  def say={
    println("hello world!")
  }
}

class  Boy(val name:String, var age:Int)

object Boy {
  def main(args: Array[String]): Unit = {
    val b1 = new Boy("熊大", 8)
    //动态混入,混入之后的类型不在是普通的类型,而是实现了特质的类型
    val b2 = new Boy("熊二", age = 7) with TraitDemo01_03
    b2.say
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值