scala-4(面向对象OOP)

本文介绍了Scala中的伴生类和伴生对象,作为Java中静态属性和方法的替代方案,伴生类与对象通过相同名称关联,提供单例特性和类的快捷访问。样例类简化了对象创建,并讨论了构造函数的使用。此外,详细阐述了伴生对象的apply方法在创建对象时的角色。同时,文章还探讨了Scala中的特质trait,强调其与Java接口的差异,以及动态混入的概念和执行顺序,展示了如何通过特质实现多继承的效果。
摘要由CSDN通过智能技术生成

伴生类和伴生对象、样例类

scala中没有static关键字,不支持创建静态属性和方法。

scala中采取的方案就是伴生类和伴生对象,两者名称一致,伴生类为class,伴生对象为object,可以理解伴生类就是java中定义的普通类,只是不能创建静态属性和函数。而伴生对象是一个单例对象,可以直接通过类名调用其中的属性和函数,使用效果和Java调用静态属性/方法类似

案例:

class School(nameIn: String, leaderIn: String, teacherNumIn: Int, addressIn: String) {
  var schoolName: String = nameIn
  var leaderName: String = leaderIn
  var teacherNum: Int = teacherNumIn
  var address: String = addressIn

  def showInfo(): Unit = {
    println(
      "name:" + schoolName +
        "  leader:" + leaderName +
        "  teacherNum:" + teacherNum +
        "  address:" + address
    )
  }
}

object School {
  def showInfo(): Unit = {
    println("object constructor")
  }
}

样例类会同时生成对应的伴生类和伴生对象,定义关键词为:case
例如:case class Student(name:String,age:Int)

构造函数

scala的构造函数分为主构造函数和辅助构造函数,主构造函数的参数列表定义在类名后面,辅助构造函数的函数名为this

// 这里是主构造函数的参数列表
class Person(nameIn: String, ageIn: Int) {
  var name: String = nameIn
  var age: Int = ageIn
  
  // 这里是辅助构造函数
  def this(){
    this("张三",18)
  }
}
  • 一个类只能有一个主构造函数,可以拥有多个辅助构造函数(函数签名不重复即可)
  • 辅助构造函数的第一行必须是this()方法
  • 每个辅助构造函数都会直接或间接的调用主构造函数
  • 当程序加载主构造函数时,会将类中代码执行一遍

伴生对象的apply方法

伴生对象的apply方法是用于创建类对象的

例如:

object Person{
  def apply(nameIn: String, ageIn: Int): Person = new Person(nameIn, ageIn)
}

方法实际就是返回new产生的类对象,在主方法中通过Person.apply("zs",22)方式也可以获得类对象,不过scala提供了更简便的写法Person("zs",22),两者效果相同

总结创建对象的方式:

object Test {
  def main(args: Array[String]): Unit = {
  	// 这里获得的是School的伴生对象
    val s1 = School
    print("s1--->")
    s1.showInfo()
    // 这里是调用了School伴生对象的无参apply方法
    val s2 = School()
    print("s2--->")
    s2.showInfo()
    // 通过new关键字创建,调用了School伴生类的辅助构造方法,当使用无参构造时,可以省略括号
    val s3 = new School
    print("s3--->")
    s3.showInfo()
    // 通过new关键字创建,同样是调用了School伴生类的辅助构造方法
    val s4 = new School()
    print("s4--->")
    s4.showInfo()
    // 调用了School伴生对象的带参apply方法
    val s5 = School("C_12", "王五", 53, "武汉")
    print("s5--->")
    s5.showInfo()
    // 调用School伴生类的主构造方法
    val s6 = new School("C_12", "王五", 53, "武汉")
    print("s6--->")
    s6.showInfo()
  }
}

class School(nameIn: String, leaderIn: String, teacherNumIn: Int, addressIn: String) {
  var schoolName: String = nameIn
  var leaderName: String = leaderIn
  var teacherNum: Int = teacherNumIn
  var address: String = addressIn

  def this() {
    this("C_11", "张三", 12, "北京")
  }

  def showInfo(): Unit = {
    println(
      "name:" + schoolName +
        "  leader:" + leaderName +
        "  teacherNum:" + teacherNum +
        "  address:" + address
    )
  }
}

object School {
  def apply(nameIn: String, leaderIn: String, teacherNumIn: Int, addressIn: String): School = new School(nameIn, leaderIn, teacherNumIn, addressIn)

  def apply(): School = new School("C_13", "李四", 32, "重庆")

  def showInfo(): Unit = {
    println("object constructor")
  }
}

输出结果

s1--->object constructor
s2--->name:C_13  leader:李四  teacherNum:32  address:重庆
s3--->name:C_11  leader:张三  teacherNum:12  address:北京
s4--->name:C_11  leader:张三  teacherNum:12  address:北京
s5--->name:C_12  leader:王五  teacherNum:53  address:武汉
s6--->name:C_12  leader:王五  teacherNum:53  address:武汉

特质trait和动态混入

特质,类似与Java接口
​ 1、trait中未被实现的方法默认是抽象方法,不需要在方法前加abstract
​ 2、子类实现trait,使用extends而不是implements
​ 3、子类方法前不需要写override关键字
​ 4、实现多个特质时,可以使用with关键字来添加其他特质

动态混入:

举例:val 对象名 = new 类名 with 特质名 [with 特质名]

注意事项:

  • 即便类是空的,对象也可以调用特质中的方法,类可以是普通类也可以是抽象类

  • 如果抽象类中有同名的方法,要先混入特质再实现方法(一般在最后使用匿名内部类一起实现)

  • 同时混入多个特质,叫做叠加特质,那么特质声明顺序从左到右,方法执行顺序从右到左

  • 动态混入创建对象过程

      1、先检测混入的第一个对象(从左向右),如果它有父类(特质也当作类),将执行父类的加载,再执行本类加载
    
      2、第一个对象加载完后,向右加载下一个特质,同样有父类先加载父类,但如果父类在之前加载过了,本次将不再重复加载
    
  • 执行动态混入的方法,先执行右边的特质的方法

  • 动态混入多个特质时,特质中的super指的时混入时,左边的特质,左边没有或者找不到才去执行父类

  • 如果想要调用具体特质的方法,可以指定 super[特质].xxx()

  • 这里标注的特质必须是当前类的直接超类

  • 如果在子特质中重写/实现了一个父特质的抽象方法,但是又使用super调用这个方法,这时方法就不是完全实现,因此需要声明为abstract override

  • 此时调用的super,在动态混入过程中,可能会指向左边的特质,此时或许就可以顺利运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值