① 构造器
Why
构造器的设计目的是为了用来初始化对象,在Scala中构造器分为主构造器
和辅助构造器
两种,辅助构造器必须调用主构造器来构造对象
,并且必须放在第一行
How
语法
class 类名(形参列表) extends 父类名(父类构造器参数列表){ // 主构造器 // 属性 var 属性名1 : 类型1 = 形参1 var 属性名2 : 类型2 = 形参2 // 辅助构造器 def this(形参列表1) { // 辅助构造器1 } def this(形参列表2) { // 辅助构造器1 } }
Demo
object ConstructDemo01 { def main(args: Array[String]): Unit = { val stu = new Student("lisi", 25) stu.print() } }class Student(inName :String, inAge :Int) { var name : String = inName var age : Int = inAge def this() { this("", 0) println("this construct") } def print(): Unit = { println(s"name = $name, age = $age") } println("main construct") }
What
Scala的主构造器本质是什么?辅助构造器呢?
如下代码是使用反编译工具得到的代码,可加班Scala底层会生成两个Java类型的构造器分别对应.其本质还是java的构造器.
package com.sweetcs.bigdata.scala.day04.chapter07._01_construct;import scala.Predef.;import scala.StringContext;import scala.reflect.ScalaSignature;import scala.runtime.BoxesRunTime;public class Student{ ...省略掉属性,现在只关注构造器 public Student() { this("", 0); Predef..MODULE$.println("this construct"); } public void print() { Predef..MODULE$.println(new StringContext(Predef..MODULE$.wrapRefArray((Object[])new String[] { "name = ", ", age = ", "" })).s(Predef..MODULE$.genericWrapArray(new Object[] { name(), BoxesRunTime.boxToInteger(age()) }))); } public Student(String inName, int inAge) { this.name = inName; this.age = inAge; Predef..MODULE$.println("main construct"); } }
Details
Scala的
构造器
不能直接调用super
.且只有主要构造器能够调用父类构造器.Scala的主构造器放在
类名之后
,并且如果有继承需在父类之后直接写明要调用的父类构造器
.如果是无参数构造器可以都省略.
class Studentn(name :String ) extends Person(sno :String) { }
Scala的
辅助构造器名字都为this
,最终
必须要能``调用到主构造器
.因为需要通过主构造器来调用父类构造器构造初始化父类成员默认的构造器访问权限是public,如果要声明为prive,需要在
构造器前加private()
class Studentn private(name :String ) { }
② 属性高级
Why
属性高级技术主要是提供更加便捷的创建属性的方式.我们需要了解每一种方式对应生成的是读写属性、还是只读、只写.
How
语法
Scala可以再构造器中直接生成属性,如果是val修饰生成
只读属性
.如果是var修饰读写属性
Scala可以使用
@BeanProperty
注解修饰属性,生成复合Bean规范的setter和getter
Demo
/** * @author sweetcs */object PropertiesAdvance { def main(args: Array[String]): Unit = { val w1 = new WorkerOne("lisi") println(w1.name) println(w1.inName) // 报错 val w2 = new WorkerTwo("wangwu") println(w2.name) println(w2.inName) // val是只读的私有属性 w2.inName = "xxx" // 报错 val w3 = new WorkerThree("xiaoming") println(w3.name) println(w3.inName) // var是 可读可写 的私有属性 w3.inName = "xiaoliu" val w4 = new WorkerFour w4.setName("lisi") w4.getName println(w4.name, w4.getName) w4.name = "wangwu" println(w4.name, w4.getName) } }class WorkerOne(inName : String) { var name = inName }class WorkerTwo(val inName : String) { var name = inName }class WorkerThree(var inName : String) { var name = inName }class WorkerFour() { // 自动生成Bean规范的setter和getter,且var name底层原有的set和get还保留 @BeanProperty var name; }
What
对应的底层反编译源码就不贴了,感兴趣的可以自己用JD-GUI反编译.
Details
使用
@BeanProperty
自动生成Bean规范
的setter
和getter
,且var name底层原有的set和get还保留
③ 对象的创建流程分析
作者:sixleaves
链接:https://www.jianshu.com/p/c63af58ef334
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦